Exemple #1
0
//---------------------------------------------------------------------------------------
// Assert that a assembly is no longer discoverable via enumeration.
//
// Notes:
//   See code:IDacDbiInterface#Enumeration for rules that we're asserting.
//   This is a debug only method. It's conceptually similar to 
//   code:CordbProcess::DbgAssertAppDomainDeleted. 
//
void CordbAssembly::DbgAssertAssemblyDeleted()
{
    GetProcess()->GetDAC()->EnumerateAssembliesInAppDomain(
        GetAppDomain()->GetADToken(),
        CordbAssembly::DbgAssertAssemblyDeletedCallback,
        this);
}
Exemple #2
0
HRESULT CordbStepper::Deactivate()
{
    if (!m_active)
        return S_OK;

    if (m_thread == NULL)
        return CORDBG_E_PROCESS_TERMINATED;

    CORDBLeftSideDeadIsOkay(GetProcess());
    CORDBSyncFromWin32StopIfNecessary(GetProcess());
    CORDBRequireProcessStateOKAndSync(GetProcess(), GetAppDomain());

    CordbProcess *process = GetProcess();

    process->Lock();

    if (!m_active) // another thread may be deactivating (e.g. step complete event)
    {
        process->Unlock();
        return S_OK;
    }

    CordbAppDomain *pAppDomain = GetAppDomain();
    _ASSERTE (pAppDomain != NULL);

    DebuggerIPCEvent event;
    process->InitIPCEvent(&event,
                          DB_IPCE_STEP_CANCEL,
                          false,
                          (void *)(pAppDomain->m_id));
    event.StepData.stepperToken = (void *) m_id;

    HRESULT hr = process->SendIPCEvent(&event, sizeof(DebuggerIPCEvent));

//  pAppDomain->Lock();

    process->m_steppers.RemoveBase(m_id);
    m_active = false;

//  pAppDomain->Unlock();

    process->Unlock();

    return hr;
}
Exemple #3
0
HRESULT CordbStepper::Step(BOOL bStepIn)
{
    if (m_thread == NULL)
        return CORDBG_E_PROCESS_TERMINATED;

    CORDBSyncFromWin32StopIfNecessary(GetProcess());
    CORDBRequireProcessStateOKAndSync(GetProcess(), GetAppDomain());

    return StepRange(bStepIn, NULL, 0);
}
Exemple #4
0
FCIMPL0(FC_BOOL_RET, SystemNative::HasShutdownStarted)
{
    FCALL_CONTRACT;

    // Return true if the EE has started to shutdown and is now going to 
    // aggressively finalize objects referred to by static variables OR
    // if someone is unloading the current AppDomain AND we have started
    // finalizing objects referred to by static variables.
    FC_RETURN_BOOL((g_fEEShutDown & ShutDown_Finalize2) || GetAppDomain()->IsFinalizing());
}
Exemple #5
0
// if the object we are creating is a proxy to another appdomain, want to create the wrapper for the
// new object in the appdomain of the proxy target
Context* ComCallWrapper::GetExecutionContext(OBJECTREF pObj, OBJECTREF* pServer )
{
    Context *pContext = NULL;

    if (pObj->GetMethodTable()->IsTransparentProxyType()) 
        pContext = CRemotingServices::GetServerContextForProxy(pObj);

    if (pContext == NULL)
        pContext = GetAppDomain()->GetDefaultContext();

    return pContext;
}
Exemple #6
0
FCIMPLEND
#endif // !FEATURE_CORECLR

FCIMPL4(void, AssemblyNameNative::Init, Object * refThisUNSAFE, OBJECTREF * pAssemblyRef, CLR_BOOL fForIntrospection, CLR_BOOL fRaiseResolveEvent)
{
    FCALL_CONTRACT;

    ASSEMBLYNAMEREF pThis = (ASSEMBLYNAMEREF) (OBJECTREF) refThisUNSAFE;
    HRESULT hr = S_OK;
    
    HELPER_METHOD_FRAME_BEGIN_1(pThis);
    
    *pAssemblyRef = NULL;

    if (pThis == NULL)
        COMPlusThrow(kNullReferenceException, W("NullReference_This"));

    Thread * pThread = GetThread();

    CheckPointHolder cph(pThread->m_MarshalAlloc.GetCheckpoint()); //hold checkpoint for autorelease

    AssemblySpec spec;
    hr = spec.InitializeSpec(&(pThread->m_MarshalAlloc), (ASSEMBLYNAMEREF *) &pThis, TRUE, FALSE); 

    if (SUCCEEDED(hr))
    {
        spec.AssemblyNameInit(&pThis,NULL);
    }
    else if ((hr == FUSION_E_INVALID_NAME) && fRaiseResolveEvent)
    {
        Assembly * pAssembly = GetAppDomain()->RaiseAssemblyResolveEvent(&spec, fForIntrospection, FALSE);

        if (pAssembly == NULL)
        {
            EEFileLoadException::Throw(&spec, hr);
        }
        else
        {
            *((OBJECTREF *) (&(*pAssemblyRef))) = pAssembly->GetExposedObject();
        }
    }
    else
    {
        ThrowHR(hr);
    }
    
    HELPER_METHOD_FRAME_END();
}
HRESULT Library_corlib_native_System_AppDomain::Unload___STATIC__VOID__SystemAppDomain( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_AppDomain* appDomainSav;
    CLR_RT_AppDomain* appDomain;
    CLR_RT_HeapBlock  hbTimeout;
    CLR_INT64*        timeout;
    bool              fRes;
    
    TINYCLR_CHECK_HRESULT(GetAppDomain( stack.ThisRef(), appDomain, appDomainSav, false ));

    hbTimeout.SetInteger( 5 * 1000 );
    
    if(stack.m_customState == 0)
    {        
        //Attempt to unload the AppDomain only once
        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.UnloadAppDomain( appDomain, stack.m_owningThread ));            
    }

    TINYCLR_CHECK_HRESULT(stack.SetupTimeout( hbTimeout, timeout ));

    fRes = true;
    while(fRes)
    {
        //Check to make sure this AppDomain is the one that caused the event to fire
        if(appDomain->m_state == CLR_RT_AppDomain::AppDomainState_Unloaded) break;

        _ASSERTE(CLR_EE_IS(UnloadingAppDomain));

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.WaitEvents( stack.m_owningThread, *timeout, CLR_RT_ExecutionEngine::c_Event_AppDomain, fRes ));
    }

    if(!fRes) TINYCLR_SET_AND_LEAVE(CLR_E_TIMEOUT);

    appDomain->DestroyInstance();

    stack.PopValue();
    
    TINYCLR_CLEANUP();

    g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( appDomainSav );    

    TINYCLR_CLEANUP_END();
}
HRESULT Library_corlib_native_System_AppDomain::GetAssemblies___SZARRAY_SystemReflectionAssembly( CLR_RT_StackFrame& stack )
{   
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();
    
    CLR_RT_AppDomain* appDomainSav = NULL;
    CLR_RT_AppDomain* appDomain;    

    TINYCLR_CHECK_HRESULT(GetAppDomain( stack.ThisRef(), appDomain, appDomainSav, true ));

    TINYCLR_CHECK_HRESULT(appDomain->GetAssemblies( stack.PushValueAndClear() ));    

    TINYCLR_CLEANUP();

    g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( appDomainSav );    

    TINYCLR_CLEANUP_END();
}
Exemple #9
0
HRESULT CordbStepper::StepOut()
{
    if (m_thread == NULL)
        return CORDBG_E_PROCESS_TERMINATED;

    CORDBSyncFromWin32StopIfNecessary(GetProcess());
    CORDBRequireProcessStateOKAndSync(GetProcess(), GetAppDomain());

    if (m_active)
    {
        //
        // Deactivate the current stepping.
        // or return an error???
        //

        HRESULT hr = Deactivate();

        if (FAILED(hr))
            return hr;
    }

    CordbProcess *process = GetProcess();

    //
    // Build step event
    //

    DebuggerIPCEvent *event =
        (DebuggerIPCEvent *) _alloca(CorDBIPC_BUFFER_SIZE);

    process->InitIPCEvent(event,
                          DB_IPCE_STEP_OUT,
                          true,
                          (void*)(GetAppDomain()->m_id));
    event->StepData.stepper = this;
    event->StepData.threadToken = m_thread->m_debuggerThreadToken;
    event->StepData.rgfMappingStop = m_rgfMappingStop;
    event->StepData.rgfInterceptStop = m_rgfInterceptStop;

    if (m_frame == NULL)
        event->StepData.frameToken = NULL;
    else
        event->StepData.frameToken = (void*) m_frame->m_id;

    event->StepData.totalRangeCount = 0;

    // Note: two-way event here...
    HRESULT hr = process->SendIPCEvent(event, CorDBIPC_BUFFER_SIZE);

    if (FAILED(hr))
        return hr;

    m_id = (unsigned long) event->StepData.stepperToken;

#ifdef _DEBUG
    CordbAppDomain *pAppDomain = GetAppDomain();
#endif
    _ASSERTE (pAppDomain != NULL);

    //AppDomain->Lock();
    process->Lock();

    process->m_steppers.AddBase(this);
    m_active = true;

    //pAppDomain->Unlock();
    process->Unlock();

    return S_OK;
}
        WRAPPER_CONTRACT;
        index = 0;
        currentStamp = 0;
    }

    void Init()
    {
        CONTRACTL
        {
            THROWS;
            GC_NOTRIGGER;
            MODE_ANY;
        }
        CONTRACTL_END;

        m_pResult = (CacheTable *)(void *) GetAppDomain()->GetLowFrequencyHeap()->AllocMem(CacheSize * sizeof(CacheTable));
        m_pHashTable = (HashTable *)(void *) GetAppDomain()->GetLowFrequencyHeap()->AllocMem(CacheSize * sizeof(HashTable));

        for (int i = 0; i < CacheSize; i ++)
            m_pHashTable[i].slot = -1;
    }

    BOOL GetFromCache(Element *pElement, CacheType& rv)
    {
        CONTRACTL
        {
            NOTHROW;
            GC_NOTRIGGER;
            MODE_ANY;
            PRECONDITION(CheckPointer(pElement));
        }
HRESULT Library_corlib_native_System_AppDomain::LoadInternal___SystemReflectionAssembly__STRING__BOOLEAN__I4__I4__I4__I4( CLR_RT_StackFrame& stack )
{
    NATIVE_PROFILE_CLR_CORE();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock*     pArgs        = &(stack.Arg1());
    CLR_RT_AppDomain*     appDomainSav;
    CLR_RT_AppDomain*     appDomain;
    CLR_RT_Assembly*      assembly;
    CLR_RT_Assembly_Index idx; 
    bool                  fVersion;
    CLR_INT16             maj, min, build, rev;
    LPCSTR                szAssembly;

    TINYCLR_CHECK_HRESULT(GetAppDomain( stack.ThisRef(), appDomain, appDomainSav, true ));

    szAssembly = pArgs[ 0 ].RecoverString(); FAULT_ON_NULL(szAssembly);    
    fVersion   = pArgs[ 1 ].NumericByRef().u8 != 0;
    maj        = pArgs[ 2 ].NumericByRef().s4;    
    min        = pArgs[ 3 ].NumericByRef().s4;
    build      = pArgs[ 4 ].NumericByRef().s4;
    rev        = pArgs[ 5 ].NumericByRef().s4;

    if(fVersion && (maj == -1 || min == -1 || build == -1 || rev == -1))
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_PARAMETER);
    }

    if(fVersion)
    {
        CLR_RECORD_VERSION ver;

        ver.iMajorVersion   = (CLR_UINT16) maj;
        ver.iMinorVersion   = (CLR_UINT16) min;
        ver.iBuildNumber    = (CLR_UINT16) build;
        ver.iRevisionNumber = (CLR_UINT16) rev;
        
        assembly = g_CLR_RT_TypeSystem.FindAssembly( szAssembly, &ver, true ); FAULT_ON_NULL_HR(assembly, CLR_E_INVALID_PARAMETER);
    }
    else
    {    
        assembly = g_CLR_RT_TypeSystem.FindAssembly( szAssembly, NULL, false ); FAULT_ON_NULL_HR(assembly, CLR_E_INVALID_PARAMETER);
    }
    
    TINYCLR_CHECK_HRESULT(appDomain->LoadAssembly( assembly ));

    {
        CLR_RT_HeapBlock&     top = stack.PushValue();
        CLR_RT_HeapBlock*     hbObj;

        idx.Set( assembly->m_idx );

        TINYCLR_CHECK_HRESULT(g_CLR_RT_ExecutionEngine.NewObjectFromIndex(top, g_CLR_RT_WellKnownTypes.m_Assembly));

        hbObj = top.Dereference();
        hbObj->SetReflection( idx );
    }

    TINYCLR_CLEANUP();

    g_CLR_RT_ExecutionEngine.SetCurrentAppDomain( appDomainSav );

    TINYCLR_CLEANUP_END();
}
Exemple #12
0
HRESULT AssemblySpec::LoadAssembly(Assembly** ppAssembly,
                                   OBJECTREF* pThrowable, /*= NULL*/
                                   OBJECTREF* pExtraEvidence, /*= NULL*/
                                   BOOL fPolicyLoad) /*= FALSE*/
{
    IAssembly* pIAssembly = NULL;

    HRESULT hr;
    Assembly *pAssembly = GetAppDomain()->FindCachedAssembly(this);
    if(pAssembly) {
        if ((pExtraEvidence != NULL) && (*pExtraEvidence != NULL))
            IfFailGo(SECURITY_E_INCOMPATIBLE_EVIDENCE);

        *ppAssembly = pAssembly;
        return S_FALSE;
    }

    PEFile *pFile;
    IfFailGo(GetAppDomain()->BindAssemblySpec(this, 
                                              &pFile, 
                                              &pIAssembly, 
                                              &pAssembly, 
                                              pExtraEvidence,
                                              pThrowable));

    // Loaded by AssemblyResolve event handler
    if (hr == S_FALSE) {

        //If loaded by the AssemblyResolve event, check that
        // the public keys are the same as in the AR.
        // However, if the found assembly is a dynamically
        // created one, security has decided to allow it.
        if (m_cbPublicKeyOrToken &&
            pAssembly->m_pManifestFile) {
                
            if (!pAssembly->m_cbPublicKey)
                IfFailGo(FUSION_E_PRIVATE_ASM_DISALLOWED);

            // Ref has the full key
            if (m_dwFlags & afPublicKey) {
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbPublicKey) ||
                    memcmp(m_pbPublicKeyOrToken, pAssembly->m_pbPublicKey, m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
            
            // Ref has a token
            else if (pAssembly->m_cbRefedPublicKeyToken) {
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbRefedPublicKeyToken) ||
                    memcmp(m_pbPublicKeyOrToken,
                           pAssembly->m_pbRefedPublicKeyToken,
                           m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
            else {
                if (!StrongNameTokenFromPublicKey(pAssembly->m_pbPublicKey,
                                                  pAssembly->m_cbPublicKey,
                                                  &pAssembly->m_pbRefedPublicKeyToken,
                                                  &pAssembly->m_cbRefedPublicKeyToken))
                    IfFailGo(StrongNameErrorInfo());
                
                if ((m_cbPublicKeyOrToken != pAssembly->m_cbRefedPublicKeyToken) ||
                    memcmp(m_pbPublicKeyOrToken,
                           pAssembly->m_pbRefedPublicKeyToken,
                           m_cbPublicKeyOrToken))
                    IfFailGo(FUSION_E_REF_DEF_MISMATCH);
            }
        }
        
        *ppAssembly = pAssembly;
        return S_OK;
    }


    // Until we can create multiple Assembly objects for a single HMODULE
    // we can only store one IAssembly* per Assembly. It is very important
    // to maintain the IAssembly* for an image that is in the load-context.
    // An Assembly in the load-from-context can bind to an assembly in the
    // load-context but not visa-versa. Therefore, if we every get an IAssembly
    // from the load-from-context we must make sure that it will never be 
    // found using a load. If it did then we could end up with Assembly dependencies
    // that are wrong. For example, if I do a LoadFrom() on an assembly in the GAC
    // and it requires another Assembly that I have preloaded in the load-from-context
    // then that dependency gets burnt into the Jitted code. Later on a Load() is
    // done on the assembly in the GAC and we single instance it back to the one
    // we have gotten from the load-from-context because the HMODULES are the same.
    // Now the dependency is wrong because it would not have the preloaded assembly
    // if the order was reversed.
    
    if (pIAssembly) {
        IFusionLoadContext *pLoadContext;
        hr = pIAssembly->GetFusionLoadContext(&pLoadContext);
        _ASSERTE(SUCCEEDED(hr));
        if (SUCCEEDED(hr)) {
            if (pLoadContext->GetContextType() == LOADCTX_TYPE_LOADFROM) {

                mdAssembly mda;
                if (FAILED(pFile->GetMDImport()->GetAssemblyFromScope(&mda))) {
                    hr = COR_E_ASSEMBLYEXPECTED;
                    goto exit;
                }

                LPCUTF8 psName;
                PBYTE pbPublicKey;
                DWORD cbPublicKey;
                AssemblyMetaDataInternal context;
                DWORD dwFlags;
                pFile->GetMDImport()->GetAssemblyProps(mda,
                                                       (const void**) &pbPublicKey,
                                                       &cbPublicKey,
                                                       NULL, // hash alg
                                                       &psName,
                                                       &context,
                                                       &dwFlags);
                
                AssemblySpec spec;
                if (FAILED(hr = spec.Init(psName, 
                                          &context, 
                                          pbPublicKey,
                                          cbPublicKey, 
                                          dwFlags)))
                    goto exit;
                    
                IAssemblyName* pFoundAssemblyName;
                if (FAILED(hr = spec.CreateFusionName(&pFoundAssemblyName, FALSE)))
                    goto exit;
                
                AssemblySink* pFoundSink = GetAppDomain()->GetAssemblySink();
                if(!pFoundSink) {
                    pFoundAssemblyName->Release();
                    hr = E_OUTOFMEMORY;
                    goto exit;
                }
                    
                IAssembly *pFoundIAssembly;
                BEGIN_ENSURE_PREEMPTIVE_GC();
                hr = FusionBind::GetAssemblyFromFusion(GetAppDomain()->GetFusionContext(),
                                                       pFoundSink,
                                                       pFoundAssemblyName,
                                                       &spec.m_CodeInfo,
                                                       &pFoundIAssembly);

                if(SUCCEEDED(hr)) {
                    DWORD dwFoundSize = MAX_PATH;
                    WCHAR wszFoundPath[MAX_PATH];
                    // Get the path to the module containing the manifest
                    if (SUCCEEDED(pFoundIAssembly->GetManifestModulePath(wszFoundPath,
                                                                         &dwFoundSize))) {
                        
                        // Keep the default context's IAssembly if the paths are the same
                        if (!_wcsicmp(wszFoundPath, pFile->GetFileName())) {
                            pIAssembly->Release();
                            pIAssembly = pFoundIAssembly;

                            // Make sure the new IAssembly isn't holding its own refcount on 
                            // the file (we've just verified we're holding the same file.)
                            // Otherwise we will leak the handle when we unload the assembly,
                            // assuming fusion decides to cache this IAssembly pointer 
                            // somewhere internally.
                            PEFile::ReleaseFusionMetadataImport(pFoundIAssembly);

                        }
                        else
                            pFoundIAssembly->Release();
                    }
                }

                pFoundAssemblyName->Release();
                pFoundSink->Release();
                END_ENSURE_PREEMPTIVE_GC();
                hr = S_OK;
            }
        exit:
            pLoadContext->Release();
        }
    }


    // Create the assembly and delay loading the main module.
    Module* pModule;
    hr = GetAppDomain()->LoadAssembly(pFile, 
                                      pIAssembly, 
                                      &pModule, 
                                      &pAssembly,
                                      pExtraEvidence, 
                                      fPolicyLoad,
                                      pThrowable);

    BEGIN_ENSURE_PREEMPTIVE_GC();
    if(SUCCEEDED(hr)) {
        *ppAssembly = pAssembly;
        /*HRESULT hrLoose =*/ GetAppDomain()->AddAssemblyToCache(this, pAssembly);
    }

    if(pIAssembly)
        pIAssembly->Release();
    END_ENSURE_PREEMPTIVE_GC();

 ErrExit:
    if (FAILED(hr) && (pThrowable!=NULL)) { 
        BEGIN_ENSURE_COOPERATIVE_GC();
        if ((pThrowable != RETURN_ON_ERROR) && (*pThrowable == NULL)) {
            if (m_pAssemblyName)
                PostFileLoadException(m_pAssemblyName, FALSE,NULL, hr, pThrowable);
            else {
                MAKE_UTF8PTR_FROMWIDE(szName, m_CodeInfo.m_pszCodeBase);
                PostFileLoadException(szName, TRUE,NULL, hr, pThrowable);
            }
        }
        END_ENSURE_COOPERATIVE_GC();
    }

    return hr;
}
Exemple #13
0
HRESULT AssemblySpec::LowLevelLoadManifestFile(PEFile** ppFile,
                                               IAssembly** ppIAssembly,
                                               Assembly **ppDynamicAssembly,
                                               OBJECTREF* pExtraEvidence,
                                               OBJECTREF* pThrowable)
{
    CANNOTTHROWCOMPLUSEXCEPTION();

    HRESULT hr = S_OK;
    IAssemblyName* pFusionAssemblyName = NULL;     // Assembly object to assembly in fusion cache

    if(!(m_pAssemblyName || m_CodeInfo.m_pszCodeBase)) {
        PostFileLoadException("", FALSE, NULL, COR_E_FILENOTFOUND, pThrowable);
        return HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND);
    }

    //
    // Check to see if this fits our rather loose idea of a reference to mscorlib.
    // If so, don't use fusion to bind it - do it ourselves.
    //

    if (IsMscorlib())
    {
        _ASSERTE(wcslen(SystemDomain::System()->BaseLibrary()) > 0);
        hr = PEFile::Create(SystemDomain::System()->BaseLibrary(), 
                            NULL, 
                            mdFileNil, 
                            TRUE, 
                            NULL, 
                            NULL, // Code base is the same as the name
                            NULL, // Extra Evidence
                            ppFile);
        _ASSERTE((*ppFile)->IsSystem());
        if (ppDynamicAssembly) *ppDynamicAssembly = NULL;
        return hr;
    }

    CQuickWSTR FusionLog;
    FusionLog.Ptr()[0]=L'\0';

    BEGIN_ENSURE_PREEMPTIVE_GC();

    Assembly *pAssembly = NULL;
    PEFile *pFile = NULL;

    hr = CreateFusionName(&pFusionAssemblyName);
    if (FAILED(hr))
        goto exit;

    hr = pFusionAssemblyName->SetProperty(ASM_NAME_NULL_CUSTOM,NULL,0); //do not look in ZAP
    if (FAILED(hr))
        goto exit;

    hr = GetAssemblyFromFusion(GetAppDomain(),
                               pFusionAssemblyName,
                               &m_CodeInfo,
                               ppIAssembly,
                               &pFile,
                               &FusionLog,
                               pExtraEvidence,
                               pThrowable);
    if(FAILED(hr)) {

            DWORD cb = 0;
            pFusionAssemblyName->GetDisplayName(NULL, &cb, 0);
            if(cb) {
                CQuickBytes qb;
                LPWSTR pwsFullName = (LPWSTR) qb.Alloc(cb*sizeof(WCHAR));

                if (SUCCEEDED(pFusionAssemblyName->GetDisplayName(pwsFullName, &cb, 0))) {
                if ((pAssembly = GetAppDomain()->RaiseAssemblyResolveEvent(pwsFullName, pThrowable)) != NULL) {
                        pFile = pAssembly->GetManifestFile();
                        hr = S_FALSE;
                    }
                }
            }

#ifdef _DEBUG
        if(FAILED(hr)) {
            if (m_pAssemblyName)
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load from full name, %s\n", m_pAssemblyName));
            else if (m_CodeInfo.m_pszCodeBase)
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load from codebase, %s\n",m_CodeInfo.m_pszCodeBase));
            else
                LOG((LF_CLASSLOADER, LL_ERROR, "Fusion could not load unknown assembly.\n"));
        }
#endif //_DEBUG

    }

 exit:
    if (SUCCEEDED(hr)) {
        if (ppFile) *ppFile = pFile;
        if (ppDynamicAssembly) *ppDynamicAssembly = pAssembly;
    }

    if(pFusionAssemblyName)
        pFusionAssemblyName->Release();

    END_ENSURE_PREEMPTIVE_GC();

    if (FAILED(hr)) {
        if (m_pAssemblyName)
            PostFileLoadException(m_pAssemblyName, FALSE,FusionLog.Ptr(), hr, pThrowable);
        else {
            MAKE_UTF8PTR_FROMWIDE(szName, m_CodeInfo.m_pszCodeBase);
            PostFileLoadException(szName, TRUE,FusionLog.Ptr(), hr, pThrowable);
        }
    }

    return hr;
}
FCIMPLEND

FCIMPL1(LPOVERLAPPED, AllocateNativeOverlapped, OverlappedDataObject* overlappedUNSAFE)
{
    FCALL_CONTRACT;

    LPOVERLAPPED lpOverlapped;

    OVERLAPPEDDATAREF   overlapped   = ObjectToOVERLAPPEDDATAREF(overlappedUNSAFE);
    OBJECTREF       userObject = overlapped->m_userObject;

    HELPER_METHOD_FRAME_BEGIN_RET_ATTRIB_2(Frame::FRAME_ATTR_NONE, overlapped, userObject);

    if (g_pOverlappedDataClass == NULL)
    {
        g_pOverlappedDataClass = MscorlibBinder::GetClass(CLASS__OVERLAPPEDDATA);
        // We have optimization to avoid creating event if IO is in default domain.  This depends on default domain 
        // can not be unloaded.
        _ASSERTE(SystemDomain::System()->DefaultDomain()->GetId().m_dwId == DefaultADID);
    }

    CONSISTENCY_CHECK(overlapped->GetMethodTable() == g_pOverlappedDataClass);

    if (userObject != NULL)
    {
        if (userObject->GetMethodTable() == g_pPredefinedArrayTypes[ELEMENT_TYPE_OBJECT]->GetMethodTable())
        {
            BASEARRAYREF asArray = (BASEARRAYREF) userObject;
            OBJECTREF *pObj = (OBJECTREF*)(asArray->GetDataPtr());
            SIZE_T num = asArray->GetNumComponents();
            SIZE_T i;
            for (i = 0; i < num; i ++)
            {
                ValidatePinnedObject(pObj[i]);
            }
        }
        else
        {
            ValidatePinnedObject(userObject);
        }
    }

    NewHolder<NATIVEOVERLAPPED_AND_HANDLE> overlappedHolder(new NATIVEOVERLAPPED_AND_HANDLE());
    overlappedHolder->m_handle = GetAppDomain()->CreateTypedHandle(overlapped, HNDTYPE_ASYNCPINNED);
    lpOverlapped = &(overlappedHolder.Extract()->m_overlapped);

    lpOverlapped->Internal = 0;
    lpOverlapped->InternalHigh = 0;
    lpOverlapped->Offset = overlapped->m_offsetLow;
    lpOverlapped->OffsetHigh = overlapped->m_offsetHigh;
    lpOverlapped->hEvent = (HANDLE)overlapped->m_eventHandle;

    overlapped->m_pNativeOverlapped = lpOverlapped;

    HELPER_METHOD_FRAME_END();
    LOG((LF_INTEROP, LL_INFO10000, "In AllocNativeOperlapped thread 0x%x\n", GetThread()));

    if (ETW_EVENT_ENABLED(MICROSOFT_WINDOWS_DOTNETRUNTIME_PROVIDER_Context, ThreadPoolIODequeue))
        FireEtwThreadPoolIOPack(lpOverlapped, overlappedUNSAFE, GetClrInstanceId());

    return lpOverlapped;
}
Exemple #15
0
HRESULT STDMETHODCALLTYPE ICorDBPrivHelperImpl::CreateManagedObject(
    /*in*/  WCHAR *wszAssemblyName,
    /*in*/  WCHAR *wszModuleName,
    /*in*/  mdTypeDef classToken,
    /*in*/  void *rawData,
    /*out*/ IUnknown **ppUnk)
{
    _ASSERTE(TypeFromToken((mdTypeDef)classToken) == mdtTypeDef);
    _ASSERTE(wszAssemblyName && wszModuleName && ppUnk);

    if (!wszAssemblyName || !wszModuleName || classToken == mdTokenNil) 
        return E_INVALIDARG;

    if (!ppUnk) 
        return E_POINTER;

    HRESULT hr = S_OK;

    BEGINCANNOTTHROWCOMPLUSEXCEPTION();

    // This will set up a managed thread object if one does not already exist
    // for this particular thread.
    Thread* pThread = SetupThread();

    if (pThread == NULL) {
        hr = E_OUTOFMEMORY;
        goto Exit;
    }
    
    // Start up COM Interop
    if (FAILED(hr = QuickCOMStartup()))
        goto Exit;

    {
    // Don't want to be interrupted...
    BOOL fWasGCEnabled = !pThread->PreemptiveGCDisabled();

    if (fWasGCEnabled)
        pThread->DisablePreemptiveGC();
    
    Assembly  *pAssembly;
    Module    *pModule;
     
    if (GetAppDomain() == NULL)
        hr = E_INVALIDARG;
    else
    {
        // Try and load the assembly, given the name provided.
        OBJECTREF pThrowable = NULL;
        GCPROTECT_BEGIN(pThrowable);

        hr = AssemblySpec::LoadAssembly(wszAssemblyName, &pAssembly, &pThrowable);

        GCPROTECT_END();

        if (SUCCEEDED(hr))
        {
            _ASSERTE(pAssembly);

            // Try and load the module, given the name provided.
            hr = pAssembly->GetModuleFromFilename(wszModuleName, &pModule);

            if (SUCCEEDED(hr))
            {
                _ASSERTE(pModule);

                // If the class isn't known,then don't try and create it.
                if (!pModule->GetMDImport()->IsValidToken(classToken))
                    hr = E_INVALIDARG;
                else
                {                    
                    COMPLUS_TRY
                    {
                        OBJECTREF obj = NULL;
                        GCPROTECT_BEGIN(obj);

                        // Now try and get the TypeHandle for the given token
                        NameHandle nameHandle(pModule, classToken);
                        TypeHandle typeHandle =
                            pAssembly->LoadTypeHandle(&nameHandle, &obj);

                        // If an exception was thrown at some point, convert
                        // it to an HRESULT
                        if (obj != NULL)
                            hr = SecurityHelper::MapToHR(obj);

                        // No longer need the object, can be GC'd if desired
                        obj = NULL;

                        if (SUCCEEDED(hr))
                        {
                            _ASSERTE(typeHandle.AsMethodTable());
                            MethodTable *pMT = typeHandle.AsMethodTable();
        
                            if (!pMT->GetClass()->IsValueClass() ||
                                pMT->ContainsPointers())
                                hr = CORDBG_E_OBJECT_IS_NOT_COPYABLE_VALUE_CLASS;

                            if (SUCCEEDED(hr))
                            {
                                // Now run the class initialiser
                                if (!pMT->CheckRunClassInit(&obj))
                                    hr = SecurityHelper::MapToHR(obj);

                                // No longer need the object, can be GC'd if
                                // desired
                                obj = NULL;

                                if (SUCCEEDED(hr))
                                {
                                    // If successful, allocate an instance of
                                    // the class
                                    
                                    // This may throw an
                                    // OutOfMemoryException, but the below
                                    // COMPLUS_CATCH should handle it.  If
                                    // the class is a ValueClass, the
                                    // created object will be a boxed
                                    // ValueClass.
                                    obj = AllocateObject(pMT);

                                    // Now create a COM wrapper around
                                    // this object.  Note that this can
                                    // also throw.
                                    *ppUnk = GetComIPFromObjectRef(&obj);
                                    _ASSERTE(ppUnk);

                                    // This is the nasty part. We're gonna
                                    // copy the raw data we're given over
                                    // the new instance of the value
                                    // class...
                                    CopyValueClass(obj->UnBox(), rawData, pMT, obj->GetAppDomain());

                                    // No longer need the object, can be GC'd
                                    // if desired
                                    obj = NULL;
                                }
                            }
                        }

                        GCPROTECT_END();  // obj
                    }
                    COMPLUS_CATCH
                    {
                        // If there's an exception, convert it to an HR
                        hr = SecurityHelper::MapToHR(GETTHROWABLE());
                    }
                    COMPLUS_END_CATCH
                }
            }
        }
    }
    
    if (fWasGCEnabled)
        pThread->EnablePreemptiveGC();

    }
Exit:
    ENDCANNOTTHROWCOMPLUSEXCEPTION();
    return (hr);
}
Exemple #16
0
HRESULT CordbStepper::StepRange(BOOL bStepIn,
                                COR_DEBUG_STEP_RANGE ranges[],
                                ULONG32 cRangeCount)
{
    VALIDATE_POINTER_TO_OBJECT_ARRAY_OR_NULL(ranges,COR_DEBUG_STEP_RANGE,
            cRangeCount, true, true);

    if (m_thread == NULL)
        return CORDBG_E_PROCESS_TERMINATED;

    CORDBSyncFromWin32StopIfNecessary(GetProcess());
    CORDBRequireProcessStateOKAndSync(GetProcess(), GetAppDomain());

    if (m_active)
    {
        //
        // Deactivate the current stepping.
        // or return an error???
        //

        HRESULT hr = Deactivate();

        if (FAILED(hr))
            return hr;
    }

    CordbProcess *process = GetProcess();

    //
    // Build step event
    //

    DebuggerIPCEvent *event =
        (DebuggerIPCEvent *) _alloca(CorDBIPC_BUFFER_SIZE);

    process->InitIPCEvent(event,
                          DB_IPCE_STEP,
                          true,
                          (void*)(GetAppDomain()->m_id));
    event->StepData.stepper = this;
    event->StepData.threadToken = m_thread->m_debuggerThreadToken;
    event->StepData.rgfMappingStop = m_rgfMappingStop;
    event->StepData.rgfInterceptStop = m_rgfInterceptStop;

    if (m_frame == NULL)
        event->StepData.frameToken = NULL;
    else
        event->StepData.frameToken = (void*) m_frame->m_id;

    event->StepData.stepIn = bStepIn != 0;

    event->StepData.totalRangeCount = cRangeCount;
    event->StepData.rangeIL = m_rangeIL;

    //
    // Send ranges.  We may have to send > 1 message.
    //

    COR_DEBUG_STEP_RANGE *rStart = &event->StepData.range;
    COR_DEBUG_STEP_RANGE *rEnd = ((COR_DEBUG_STEP_RANGE *)
                                  (((BYTE *)event) +
                                   CorDBIPC_BUFFER_SIZE)) - 1;
    int n = cRangeCount;
    if (n > 0)
    {
        while (n > 0)
        {
            COR_DEBUG_STEP_RANGE *r = rStart;

            if (n < rEnd - r)
                rEnd = r + n;

            while (r < rEnd)
                *r++ = *ranges++;

            n -= event->StepData.rangeCount = r - rStart;

            //
            // Send step event (two-way event here...)
            //

            HRESULT hr = process->SendIPCEvent(event,
                                               CorDBIPC_BUFFER_SIZE);
            if (FAILED(hr))
                return hr;
        }
    }
    else
    {
        //
        // Send step event without any ranges (two-way event here...)
        //

        HRESULT hr = process->SendIPCEvent(event,
                                           CorDBIPC_BUFFER_SIZE);

        if (FAILED(hr))
            return hr;
    }

    m_id = (unsigned long) event->StepData.stepperToken;

    LOG((LF_CORDB,LL_INFO10000, "CS::SR: m_id:0x%x | 0x%x \n", m_id,
         event->StepData.stepperToken));

#ifdef _DEBUG
    CordbAppDomain *pAppDomain = GetAppDomain();
#endif
    _ASSERTE (pAppDomain != NULL);

//  pAppDomain->Lock();
    process->Lock();

    process->m_steppers.AddBase(this);
    m_active = true;

//    pAppDomain->Unlock();
    process->Unlock();

    return S_OK;
}
Exemple #17
0
HRESULT CordbFunctionBreakpoint::Activate(BOOL bActive)
{
    if (bActive == (m_active == true) )
        return S_OK;

    if (m_code == NULL)
        return CORDBG_E_PROCESS_TERMINATED;

    CORDBLeftSideDeadIsOkay(GetProcess());

    HRESULT hr;

    //
    //
    CordbProcess *process = GetProcess();
    process->ClearPatchTable(); //if we add something, then the
    //right side view of the patch table is no longer valid
    DebuggerIPCEvent *event =
        (DebuggerIPCEvent *) _alloca(CorDBIPC_BUFFER_SIZE);

    CordbAppDomain *pAppDomain = GetAppDomain();
    _ASSERTE (pAppDomain != NULL);
    if (bActive)
    {
        CORDBRequireProcessStateOK(GetProcess());

        CORDBSyncFromWin32StopIfStopped(GetProcess());

        process->InitIPCEvent(event,
                              DB_IPCE_BREAKPOINT_ADD,
                              true,
                              (void *)pAppDomain->m_id);
        event->BreakpointData.funcMetadataToken
            = m_code->m_function->m_token;
        event->BreakpointData.funcDebuggerModuleToken
            = (void *) m_code->m_function->m_module->m_debuggerModuleToken;
        event->BreakpointData.isIL = m_code->m_isIL ? true : false;
        event->BreakpointData.offset = m_offset;
        event->BreakpointData.breakpoint = this;

        // Note: we're sending a two-way event, so it blocks here
        // until the breakpoint is really added and the reply event is
        // copied over the event we sent.
        hr = process->SendIPCEvent(event, CorDBIPC_BUFFER_SIZE);
        if (FAILED(hr))
            return hr;

        // If something went wrong, bail.
        if (FAILED(event->hr))
            return event->hr;

        m_id = (unsigned long)event->BreakpointData.breakpointToken;

        // If we weren't able to allocate the BP, we should have set the
        // hr on the left side.
        _ASSERTE(m_id != 0);

        pAppDomain->Lock();

        pAppDomain->m_breakpoints.AddBase(this);
        m_active = true;

        pAppDomain->Unlock();
    }
    else
    {
        CordbAppDomain *pAppDomain = GetAppDomain();
        _ASSERTE (pAppDomain != NULL);

        if (CORDBCheckProcessStateOK(process) && (pAppDomain->m_fAttached == TRUE))
        {
            CORDBSyncFromWin32StopIfStopped(GetProcess());

            process->InitIPCEvent(event,
                                  DB_IPCE_BREAKPOINT_REMOVE,
                                  false,
                                  (void *)pAppDomain->m_id);
            event->BreakpointData.breakpointToken = (void *) m_id;

            hr = process->SendIPCEvent(event, CorDBIPC_BUFFER_SIZE);
        }
        else
            hr = CORDBHRFromProcessState(process, pAppDomain);

        pAppDomain->Lock();

        pAppDomain->m_breakpoints.RemoveBase(m_id);
        m_active = false;

        pAppDomain->Unlock();

    }

    return hr;
}