HRESULT CorHost::SwitchInLogicalThreadState(DWORD *pFiberCookie) { if (!pFiberCookie) return E_POINTER; CANNOTTHROWCOMPLUSEXCEPTION(); // Case Cookie to thread object and add to tls #ifdef _DEBUG LPVOID tls = TlsGetValue(GetThreadTLSIndex()); _ASSERT(tls == NULL); #endif if (TlsSetValue(GetThreadTLSIndex(), pFiberCookie)) { Thread *pThread = GetThread(); if (!pThread) return E_UNEXPECTED; // We redundantly keep the domain in its own TLS slot, for faster access from // stubs LPVOID pDomain = pThread->GetDomain(); TlsSetValue(GetAppDomainTLSIndex(), pDomain); #ifdef _DEBUG // Make debugging easier ((Thread *) pFiberCookie)->SetThreadId(::GetCurrentThreadId()); #endif return S_OK; } else return E_FAIL; }
STDMETHODIMP ComCallWrapper::InvokeByName(LPCWSTR MemberName, INT32 BindingFlags, INT32 ArgCount, VARIANT *ArgList, VARIANT *pRetVal) { HRESULT hr = S_OK; InvokeByNameArgs args; if (pRetVal) VariantClear(pRetVal); Thread* pThread = SetupThread(); if (pThread == NULL) return E_OUTOFMEMORY; BEGINCANNOTTHROWCOMPLUSEXCEPTION(); BEGIN_ENSURE_COOPERATIVE_GC(); args.pThis = this; args.MemberName = MemberName; args.BindingFlags = BindingFlags; args.ArgCount = ArgCount; args.ArgList = ArgList; args.pRetVal = pRetVal; COMPLUS_TRY { // go through AppDomain callback if we are running in wrong AppDomain if (m_dwDomainId != pThread->GetDomain()->GetId()) { pThread->DoADCallBack(m_pContext, InvokeByNameCallback, &args); } else { InvokeByNameCallback(&args); } } COMPLUS_CATCH { hr = SetupErrorInfo(GETTHROWABLE()); } COMPLUS_END_CATCH END_ENSURE_COOPERATIVE_GC(); ENDCANNOTTHROWCOMPLUSEXCEPTION(); return hr; }
void DacDbiInterfaceImpl::EnumerateInternalFrames(VMPTR_Thread vmThread, FP_INTERNAL_FRAME_ENUMERATION_CALLBACK fpCallback, void * pUserData) { DD_ENTER_MAY_THROW; DebuggerIPCE_STRData frameData; Thread * pThread = vmThread.GetDacPtr(); Frame * pFrame = pThread->GetFrame(); AppDomain * pAppDomain = pThread->GetDomain(INDEBUG(TRUE)); // This used to be only true for Enter-Managed chains. // Since we don't have chains anymore, this can always be false. frameData.quicklyUnwound = false; frameData.eType = DebuggerIPCE_STRData::cStubFrame; while (pFrame != FRAME_TOP) { // check if the internal frame is interesting frameData.stubFrame.frameType = GetInternalFrameType(pFrame); if (frameData.stubFrame.frameType != STUBFRAME_NONE) { frameData.fp = FramePointer::MakeFramePointer(PTR_HOST_TO_TADDR(pFrame)); frameData.vmCurrentAppDomainToken.SetHostPtr(pAppDomain); MethodDesc * pMD = pFrame->GetFunction(); #if defined(FEATURE_COMINTEROP) if (frameData.stubFrame.frameType == STUBFRAME_U2M) { _ASSERTE(pMD == NULL); // U2M transition frame generally don't store the target MD because we know what the target // is by looking at the callee stack frame. However, for reverse COM interop, we can try // to get the MD for the interface. // // Note that some reverse COM interop cases don't have an intermediate interface MD, so // pMD may still be NULL. // // Even if there is an MD on the ComMethodFrame, it could be in a different appdomain than // the ComMethodFrame itself. The only known scenario is a cross-appdomain reverse COM // interop call. We need to check for this case. The end result is that GetFunction() and // GetFunctionToken() on ICDInternalFrame will return NULL. // Minidumps without full memory don't guarantee to capture the CCW since we can do without // it. In this case, pMD will remain NULL. EX_TRY_ALLOW_DATATARGET_MISSING_MEMORY { if (pFrame->GetVTablePtr() == ComMethodFrame::GetMethodFrameVPtr()) { ComMethodFrame * pCOMFrame = dac_cast<PTR_ComMethodFrame>(pFrame); PTR_VOID pUnkStackSlot = pCOMFrame->GetPointerToArguments(); PTR_IUnknown pUnk = dac_cast<PTR_IUnknown>(*dac_cast<PTR_TADDR>(pUnkStackSlot)); ComCallWrapper * pCCW = ComCallWrapper::GetWrapperFromIP(pUnk); if (!pCCW->NeedToSwitchDomains(pAppDomain->GetId())) { ComCallMethodDesc * pCMD = NULL; pCMD = dac_cast<PTR_ComCallMethodDesc>(pCOMFrame->ComMethodFrame::GetDatum()); pMD = pCMD->GetInterfaceMethodDesc(); } } } EX_END_CATCH_ALLOW_DATATARGET_MISSING_MEMORY } #endif // FEATURE_COMINTEROP Module * pModule = (pMD ? pMD->GetModule() : NULL); DomainFile * pDomainFile = (pModule ? pModule->GetDomainFile(pAppDomain) : NULL); if (frameData.stubFrame.frameType == STUBFRAME_FUNC_EVAL) { FuncEvalFrame * pFEF = dac_cast<PTR_FuncEvalFrame>(pFrame); DebuggerEval * pDE = pFEF->GetDebuggerEval(); frameData.stubFrame.funcMetadataToken = pDE->m_methodToken; frameData.stubFrame.vmDomainFile.SetHostPtr( pDE->m_debuggerModule ? pDE->m_debuggerModule->GetDomainFile() : NULL); frameData.stubFrame.vmMethodDesc = VMPTR_MethodDesc::NullPtr(); } else { frameData.stubFrame.funcMetadataToken = (pMD == NULL ? NULL : pMD->GetMemberDef()); frameData.stubFrame.vmDomainFile.SetHostPtr(pDomainFile); frameData.stubFrame.vmMethodDesc.SetHostPtr(pMD); } // invoke the callback fpCallback(&frameData, pUserData); }