Ejemplo n.º 1
0
// Implement public interface
HRESULT CordbAppDomain::GetModuleFromMetaDataInterface(
                                                  IUnknown *pIMetaData,
                                                  ICorDebugModule **ppModule)
{
    PUBLIC_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    VALIDATE_POINTER_TO_OBJECT(pIMetaData, IUnknown *);
    VALIDATE_POINTER_TO_OBJECT(ppModule, ICorDebugModule **);

    

    HRESULT hr = S_OK;

    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());

    *ppModule = NULL;

    EX_TRY
    {
        CordbModule * pModule = GetModuleFromMetaDataInterface(pIMetaData);
        _ASSERTE(pModule != NULL); // thrown on error
        
        *ppModule = static_cast<ICorDebugModule*> (pModule);
        pModule->ExternalAddRef();        
    }
    EX_CATCH_HRESULT(hr);


    return hr;
}
Ejemplo n.º 2
0
HRESULT CordbAppDomain::EnumerateSteppers(ICorDebugStepperEnum **ppSteppers)
{
    PUBLIC_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
    VALIDATE_POINTER_TO_OBJECT(ppSteppers,ICorDebugStepperEnum **);

    HRESULT hr = S_OK;
    EX_TRY
    {
        //
        // !!! m_steppers may be modified while user is enumerating,
        // if steppers complete (if process is running)
        //

        RSInitHolder<CordbHashTableEnum> pEnum;
        CordbHashTableEnum::BuildOrThrow(
            GetProcess(), 
            GetProcess()->GetContinueNeuterList(),  // ownership
            &(m_pProcess->m_steppers),
            IID_ICorDebugStepperEnum,
            pEnum.GetAddr());

        pEnum.TransferOwnershipExternal(ppSteppers);
    }
    EX_CATCH_HRESULT(hr);
    return hr;
}
Ejemplo n.º 3
0
HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount, CORDB_REGISTER regBuffer[])
{
    PUBLIC_REENTRANT_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());

    UINT iRegister = 0;

    VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true);
    
    // @ARMTODO: floating point support

    for (int i = REGISTER_INSTRUCTION_POINTER;
         i <= REGISTER_ARM_LR && iRegister < regCount;
         i++)
    {
        if (mask &  SETBITULONG64(i))
        {
            switch (i)
            {
            case REGISTER_INSTRUCTION_POINTER: 
                regBuffer[iRegister++] = m_rd->PC; break;
            case REGISTER_STACK_POINTER:
                regBuffer[iRegister++] = m_rd->SP; break;
            case REGISTER_ARM_R0:
                regBuffer[iRegister++] = m_rd->R0; break;
            case REGISTER_ARM_R1:
                regBuffer[iRegister++] = m_rd->R1; break;
            case REGISTER_ARM_R2:
                regBuffer[iRegister++] = m_rd->R2; break;
            case REGISTER_ARM_R3:
                regBuffer[iRegister++] = m_rd->R3; break;
            case REGISTER_ARM_R4:
                regBuffer[iRegister++] = m_rd->R4; break;
            case REGISTER_ARM_R5:
                regBuffer[iRegister++] = m_rd->R5; break;
            case REGISTER_ARM_R6:
                regBuffer[iRegister++] = m_rd->R6; break;
            case REGISTER_ARM_R7:
                regBuffer[iRegister++] = m_rd->R7; break;
            case REGISTER_ARM_R8:
                regBuffer[iRegister++] = m_rd->R8; break;
            case REGISTER_ARM_R9:
                regBuffer[iRegister++] = m_rd->R9; break;
            case REGISTER_ARM_R10:
                regBuffer[iRegister++] = m_rd->R10; break;
            case REGISTER_ARM_R11:
                regBuffer[iRegister++] = m_rd->R11; break;
            case REGISTER_ARM_R12:
                regBuffer[iRegister++] = m_rd->R12; break;
            case REGISTER_ARM_LR:
                regBuffer[iRegister++] = m_rd->LR; break;
            }
        }
    }

    _ASSERTE (iRegister <= regCount);
    return S_OK;
}
Ejemplo n.º 4
0
HRESULT CordbAppDomain::Attach()
{
    PUBLIC_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(m_pProcess);

    return S_OK;
}
Ejemplo n.º 5
0
//-----------------------------------------------------------------------------
// Get the full associated XML for the MDA. This may be empty.
// This could be a potentially expensive operation if the xml stream is large.
// See the MDA documentation for the schema for this XML stream. 
// See CopyOutString for parameter details.
//-----------------------------------------------------------------------------
HRESULT CordbMDA::GetXML(ULONG32 cchName, ULONG32 * pcchName, WCHAR szName[])
{
    PUBLIC_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
    
    return CopyOutString(m_szXml, cchName, pcchName, szName);
}
Ejemplo n.º 6
0
HRESULT CordbAppDomain::SetAllThreadsDebugState(CorDebugThreadState state,
                                   ICorDebugThread *pExceptThisThread)
{
    PUBLIC_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());

    return m_pProcess->SetAllThreadsDebugState(state, pExceptThisThread);
}
Ejemplo n.º 7
0
//-----------------------------------------------------------------------------
// Thread that the MDA is fired on. We use the os tid instead of an ICDThread in case an MDA is fired on a 
// native thread (or a managed thread that hasn't yet entered managed code and so we don't have a ICDThread
// object for it yet)
//-----------------------------------------------------------------------------
HRESULT CordbMDA::GetOSThreadId(DWORD * pOsTid)
{
    PUBLIC_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());

    if (pOsTid == NULL)
    {
        return E_INVALIDARG;
    }
    *pOsTid = this->m_dwOSTID;
    return S_OK;
}
Ejemplo n.º 8
0
//-----------------------------------------------------------------------------
// Get flags for this MDA object.
//-----------------------------------------------------------------------------
HRESULT CordbMDA::GetFlags(CorDebugMDAFlags * pFlags)
{
    PUBLIC_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());

    if (pFlags == NULL)
    {
        return E_INVALIDARG;
    }
    *pFlags = this->m_flags;
    return S_OK;
}
Ejemplo n.º 9
0
HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount,
                                       CORDB_REGISTER regBuffer[])
{ 
    PUBLIC_REENTRANT_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());

    UINT iRegister = 0;

    VALIDATE_POINTER_TO_OBJECT_ARRAY(regBuffer, CORDB_REGISTER, regCount, true, true);
    
    // @ARM64TODO: floating point support

    for (int i = REGISTER_ARM64_X0;
         i <= REGISTER_ARM64_PC && iRegister < regCount;
         i++)
    {
        if (mask &  SETBITULONG64(i))
        {
            if ((i >= REGISTER_ARM64_X0) && (i <= REGISTER_ARM64_X28))
            {
                regBuffer[iRegister++] = m_rd->X[i - REGISTER_ARM64_X0];
                continue;
            }

            switch (i)
            {
            case REGISTER_ARM64_PC: 
                regBuffer[iRegister++] = m_rd->PC; break;
            case REGISTER_ARM64_SP:
                regBuffer[iRegister++] = m_rd->SP; break;
            case REGISTER_ARM64_FP:
                regBuffer[iRegister++] = m_rd->FP; break;
            case REGISTER_ARM64_LR:
                regBuffer[iRegister++] = m_rd->LR; break;
            default:
                _ASSERTE(false); break;
            }
        }
    }

    _ASSERTE (iRegister <= regCount);
    return S_OK;
}
Ejemplo n.º 10
0
HRESULT CordbAppDomain::EnumerateBreakpoints(ICorDebugBreakpointEnum **ppBreakpoints)
{
    PUBLIC_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());
    VALIDATE_POINTER_TO_OBJECT(ppBreakpoints, ICorDebugBreakpointEnum **);

    HRESULT hr = S_OK;
    EX_TRY
    {
        RSInitHolder<CordbHashTableEnum> pEnum;
        CordbHashTableEnum::BuildOrThrow(
            this, 
            GetProcess()->GetContinueNeuterList(), // ownership
            &m_breakpoints,
            IID_ICorDebugBreakpointEnum,
            pEnum.GetAddr());

        pEnum.TransferOwnershipExternal(ppBreakpoints);
    }
    EX_CATCH_HRESULT(hr);
    return hr;
}
Ejemplo n.º 11
0
//-----------------------------------------------------------------------------
// Get a ICorDebugValue for a static field on this class.
//
// Parameters:
//   fieldDef - metadata token for field on this class. Can not be from an 
//      inherited class.
//   pFrame - frame used to resolve Thread-static, AppDomain-static, etc.
//   ppValue - OUT: gets value of the field.
//
// Returns:
//    S_OK on success.
//    CORDBG_E_STATIC_VAR_NOT_AVAILABLE 
//-----------------------------------------------------------------------------
HRESULT CordbClass::GetStaticFieldValue(mdFieldDef fieldDef,
                                        ICorDebugFrame *pFrame,
                                        ICorDebugValue **ppValue)
{
    PUBLIC_REENTRANT_API_ENTRY(this);
    FAIL_IF_NEUTERED(this);
    VALIDATE_POINTER_TO_OBJECT(ppValue, ICorDebugValue **);
    ATT_REQUIRE_STOPPED_MAY_FAIL(GetProcess());

    HRESULT          hr = S_OK;
    *ppValue = NULL;
    BOOL             fEnCHangingField = FALSE;


    IMetaDataImport * pImport = NULL;
    EX_TRY
    {
        pImport = GetModule()->GetMetaDataImporter(); // throws

        // Validate the token.
        if (!pImport->IsValidToken(fieldDef) || (TypeFromToken(fieldDef) != mdtFieldDef))
        {
            ThrowHR(E_INVALIDARG);
        }

        // Make sure we have enough info about the class.
        Init();

        // Uninstantiated generics (eg, Foo<T>) don't have static data. Must use instantiated (eg Foo<int>)
        // But all CordbClass instances are uninstantiated. So this should fail for all generic types.
        // Normally, debuggers should be using ICorDebugType instead.
        // Though in the forward compat case, they'll hit this.
        if (HasTypeParams())
        {
            ThrowHR(CORDBG_E_STATIC_VAR_NOT_AVAILABLE);
        }


        // Lookup the field given its metadata token.
        FieldData *pFieldData;

        hr = GetFieldInfo(fieldDef, &pFieldData);

        // This field was added by EnC, need to use EnC specific code path
        if (hr == CORDBG_E_ENC_HANGING_FIELD)
        {
            // Static fields added with EnC hang off the EnCFieldDesc
            hr = GetEnCHangingField(fieldDef,
                &pFieldData,
                NULL);

            if (SUCCEEDED(hr))
            {
                fEnCHangingField = TRUE;
            }
            // Note: the FieldOffset in pFieldData has been cooked to produce
            // the correct address of the field in the syncBlock.
            // @todo: extend Debugger_IPCEFieldData so we don't have to cook the offset here
        }

        IfFailThrow(hr);

        {
            Instantiation emptyInst;

            hr = CordbClass::GetStaticFieldValue2(GetModule(),
                pFieldData,
                fEnCHangingField,
                &emptyInst,
                pFrame,
                ppValue);
            // Let hr fall through
        }
    }
    EX_CATCH_HRESULT(hr);

    // Translate Failure HRs.
    if (pImport != NULL)
    {
        hr = CordbClass::PostProcessUnavailableHRESULT(hr, pImport, fieldDef);
    }

    return hr;

}