void ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags) { SVR::gc_heap::n_heaps.EnumMem(); DacEnumMemoryRegion(SVR::gc_heap::g_heaps.GetAddr(), sizeof(TADDR) * SVR::gc_heap::n_heaps); SVR::gc_heap::g_heaps.EnumMem(); for (int i=0;i<SVR::gc_heap::n_heaps;i++) { SVR::gc_heap *pHeap = PTR_SVR_gc_heap(SVR::gc_heap::g_heaps[i]); DacEnumMemoryRegion(PTR_HOST_TO_TADDR(pHeap), sizeof(SVR::gc_heap)); DacEnumMemoryRegion((TADDR)pHeap->finalize_queue,sizeof(SVR::CFinalize)); // enumerating the generations from max (which is normally gen2) to max+1 gives you // the segment list for all the normal segements plus the large heap segment (max+1) // this is the convention in the GC so it is repeated here for (ULONG i = GCHeap::GetMaxGeneration(); i <= GCHeap::GetMaxGeneration()+1; i++) { __DPtr<SVR::heap_segment> seg = (TADDR)pHeap->generation_table[i].start_segment; while (seg) { DacEnumMemoryRegion(PTR_HOST_TO_TADDR(seg), sizeof(SVR::heap_segment)); seg = (TADDR)(seg->next); } } } }
void ClrDataAccess::EnumSvrGlobalMemoryRegions(CLRDataEnumMemoryFlags flags) { SUPPORTS_DAC; g_gcDacGlobals->n_heaps.EnumMem(); DacEnumMemoryRegion(g_gcDacGlobals->g_heaps.GetAddr(), sizeof(TADDR) * *g_gcDacGlobals->n_heaps); g_gcDacGlobals->gc_structures_invalid_cnt.EnumMem(); g_gcDacGlobals->g_heaps.EnumMem(); for (int i=0; i < *g_gcDacGlobals->n_heaps; i++) { DPTR(dac_gc_heap) pHeap = HeapTableIndex(g_gcDacGlobals->g_heaps, i); size_t gen_table_size = g_gcDacGlobals->generation_size * (*g_gcDacGlobals->max_gen + 1); DacEnumMemoryRegion(dac_cast<TADDR>(pHeap), sizeof(dac_gc_heap)); DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->finalize_queue), sizeof(dac_finalize_queue)); DacEnumMemoryRegion(dac_cast<TADDR>(pHeap->generation_table), gen_table_size); // enumerating the generations from max (which is normally gen2) to max+1 gives you // the segment list for all the normal segements plus the large heap segment (max+1) // this is the convention in the GC so it is repeated here for (ULONG i = *g_gcDacGlobals->max_gen; i <= *g_gcDacGlobals->max_gen +1; i++) { DPTR(dac_heap_segment) seg = ServerGenerationTableIndex(pHeap, i)->start_segment; while (seg) { DacEnumMemoryRegion(PTR_HOST_TO_TADDR(seg), sizeof(dac_heap_segment)); seg = seg->next; } } } }
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); }
bool StressLog::Initialize() { ThreadStressLog* logs = 0; ThreadStressLog* curThreadStressLog = this->logs; unsigned __int64 lastTimeStamp = 0; // timestamp of last log entry while(curThreadStressLog != 0) { if (!curThreadStressLog->IsReadyForRead()) { if (curThreadStressLog->origCurPtr == NULL) curThreadStressLog->origCurPtr = curThreadStressLog->curPtr; // avoid repeated calls into this function StressLogChunk * head = curThreadStressLog->chunkListHead; StressLogChunk * curChunk = head; bool curPtrInitialized = false; do { if (!curChunk->IsValid ()) { // TODO: Report corrupt chunk PTR_HOST_TO_TADDR(curChunk) } if (!curPtrInitialized && curChunk == curThreadStressLog->curWriteChunk) { // adjust curPtr to the debugger's address space curThreadStressLog->curPtr = (StressMsg *)((UInt8 *)curChunk + ((UInt8 *)curThreadStressLog->curPtr - (UInt8 *)PTR_HOST_TO_TADDR(curChunk))); curPtrInitialized = true; } curChunk = curChunk->next; } while (curChunk != head); if (!curPtrInitialized) { delete curThreadStressLog; return false; } // adjust readPtr and curPtr if needed curThreadStressLog->Activate (NULL); } curThreadStressLog = curThreadStressLog->next; } return true; }