internal DbgStackFrameInfo(DbgEngDebugger debugger, DbgUModeThreadInfo thread, DEBUG_STACK_FRAME_EX nativeFrame, ClrStackFrame managedFrame) : this(debugger, thread, nativeFrame, managedFrame, true) { }
} // end property Context private static DbgUModeThreadInfo _ValidateThread(DbgUModeThreadInfo thread) { if (null == thread) { throw new ArgumentNullException("thread"); } return(thread); } // end _ValidateThread()
internal DbgStackFrameInfo(DbgEngDebugger debugger, DbgUModeThreadInfo thread, DEBUG_STACK_FRAME_EX nativeFrame, ClrStackFrame managedFrame, bool alreadySearchManagedFrames) : base(debugger) { if (null == thread) { throw new ArgumentNullException("thread"); } NativeFrameEx = nativeFrame; Thread = thread; m_managedFrame = managedFrame; m_alreadySearchedManagedFrames = alreadySearchManagedFrames; } // end constructor()
internal ulong GetImplicitThreadLocalStorageForThread(DbgUModeThreadInfo thread) { ulong tlsPointer = thread.ImplicitTlsStorage; if (0 == tlsPointer) { return(0); } if (-1 == m_implicitThreadLocalStorageIndex) { // In the TEB is a block of pointers to per-DLL TLS storage. Which pointer // is the one for our DLL? To answer that, we look in the PE header. var ntHeaders = Debugger.ReadImageNtHeaders(BaseAddress); if (ntHeaders.OptionalHeader.NumberOfRvaAndSizes <= (uint)ImageDirectoryEntry.TLS /* 9 */) { return(0); } uint sizeOfTlsDir; ulong addrOfTlsDir; // TODO: The names of the data directories could be improved... addrOfTlsDir = BaseAddress + ntHeaders.OptionalHeader.DataDirectory9.VirtualAddress; sizeOfTlsDir = ntHeaders.OptionalHeader.DataDirectory9.Size; if (sizeOfTlsDir < (3 * Debugger.PointerSize)) { LogManager.Trace("Unexpected TLS directory size: {0:x}", ntHeaders.OptionalHeader.DataDirectory9.Size); return(0); } else if (0 == ntHeaders.OptionalHeader.DataDirectory9.VirtualAddress) { LogManager.Trace("Unexpected TLS VA (0)."); return(0); } // The /address/ of the index is stored in the third pointer in the "TLS // directory" (at addrOfTlsDir) (from the PE/COFF spec). // Offset Size Field Description // (PE32/ (PE32/ // PE32+) PE32+) // // 0 4/8 Raw Data The starting address of the TLS template. The template is a // Start VA block of data that is used to initialize TLS data. The // system copies all of this data each time a thread is // created, so it must not be corrupted. Note that this address // is not an RVA; it is an address for which there should be a // base relocation in the .reloc section. // // 4/8 4/8 Raw Data The address of the last byte of the TLS, except for the zero // End VA fill. As with the Raw Data Start VA field, this is a VA, not // an RVA. // // 8/16 4/8 Address of The location to receive the TLS index, which the loader // Index assigns. This location is in an ordinary data section, so it // can be given a symbolic name that is accessible to the // program. // ulong addrOfThisModsTlsIndex = Debugger.ReadMemSlotInPointerArray(addrOfTlsDir, 2); // I don't know if the index itself is also pointer-sized... I'll just // read a DWORD's-worth. m_implicitThreadLocalStorageIndex = Debugger.ReadMemAs_Int32(addrOfThisModsTlsIndex); } return(Debugger.ReadMemSlotInPointerArray(tlsPointer, (uint)m_implicitThreadLocalStorageIndex)); } // end GetImplicitThreadLocalStorageForThread()
internal DbgStackFrameInfo(DbgEngDebugger debugger, DbgUModeThreadInfo thread, DEBUG_STACK_FRAME_EX nativeFrame) : this(debugger, thread, nativeFrame, null, false) { }
internal DbgStackInfo(DbgUModeThreadInfo thread, int maxFrames) : base(_ValidateThread(thread).Debugger) { m_thread = thread; MaxFrameCount = maxFrames; } // end constructor
} // end _ValidateThread() internal DbgStackInfo(DbgUModeThreadInfo thread) : this(thread, 0) { }
internal DbgThreadContainer(NsContainer <DbgUModeThreadInfo> nsThread) : base(nsThread) { Thread = nsThread.RepresentedObject; } // end constructor