public void PrintManagedCallStacks() { //Threads test, get info of all managed threads found in dump context.WriteInfo("--- Managed callstacks ---"); if (context.Runtime != null) { foreach (ClrThread thread in context.Runtime.Threads) { if (!thread.IsAlive) { continue; } context.WriteInfo("Thread {0}, managed id: {1}:", thread.OSThreadId, thread.ManagedThreadId); context.WriteInfo("GC mode: {0} ", thread.GcMode); context.WriteInfo("Thread type: {0}", thread); context.WriteInfo("Callstack: {0:X} - {1:X}", thread.StackBase, thread.StackLimit); // get last thrown exception of thread ClrException lastException = thread.CurrentException; if (lastException != null) { this.PrintException(lastException); } // walk each stack frame foreach (ClrStackFrame frame in thread.StackTrace) { SDFileAndLineNumber info = frame.GetSourceLocation(); context.WriteLine("{0,12:X} {1,12:X} {2} - {3}:{4}", frame.StackPointer, frame.InstructionPointer, frame.DisplayString, info.File, info.Line); } context.WriteLine(null); } context.WriteInfo("Total amount of all (managed) threads: " + context.Runtime.Threads.Count); } }
// ClrException.Message occasionally throws NullReferenceException even though the exception isn't null public static string GetExceptionMessageSafe(this ClrException exception) { try { return(exception.Message); } catch (Exception) { return("<null>"); } }
public void SetException() { ClrException currentEx = _thread.CurrentException; if (currentEx is ClrException ex) { CurrentException = $"Exception: {ex.Type.Name}, HResult= {ex.HResult}"; } else { CurrentException = ""; } }
internal static void TestProperties(ClrRuntime runtime) { ClrThread thread = runtime.Threads.Where(t => !t.IsFinalizer).Single(); ClrException ex = thread.CurrentException; Assert.NotNull(ex); ExceptionTestData testData = TestTargets.NestedExceptionData; Assert.Equal(testData.OuterExceptionMessage, ex.Message); Assert.Equal(testData.OuterExceptionType, ex.Type.Name); Assert.NotNull(ex.Inner); }
public override void Init() { Exceptions = new List <ClrExceptionInformation>(); ClrException exception = ClrDump.Eval(() => ClrThread.CurrentException); while (exception != null) { Exceptions.Add(new ClrExceptionInformation(ClrDump, exception)); exception = ClrDump.Eval(() => exception.Inner); } dlvExceptions.Objects = Exceptions; }
internal static void TestProperties(ClrRuntime runtime) { ClrThread thread = runtime.GetMainThread(); ClrException?exNullable = thread.CurrentException; Assert.NotNull(exNullable); ClrException ex = exNullable.GetValueOrDefault(); ExceptionTestData testData = TestTargets.NestedExceptionData; Assert.Equal(testData.OuterExceptionMessage, ex.Message); Assert.Equal(testData.OuterExceptionType, ex.Type.Name); Assert.NotNull(ex.Inner); }
public EventInformation GetLastEvent() { var debugControl = (IDebugControl)_target.DebuggerInterface; DEBUG_EVENT eventType; uint processId, threadIndex; IntPtr extraInformation = IntPtr.Zero; const uint extraInformationSize = 0; uint extraInformationUsed; const int descriptionSize = 1024; var description = new StringBuilder(descriptionSize); uint descriptionUsed; int h = debugControl.GetLastEventInformation(out eventType, out processId, out threadIndex, extraInformation, extraInformationSize, out extraInformationUsed, description, descriptionSize, out descriptionUsed); if (h != 0) { throw new ApplicationException("Could not retrieve last event information: " + h); } var debugSystemObjects = (IDebugSystemObjects)_target.DebuggerInterface; const uint count = 1; var sysIds = new uint[count]; if (0 != (h = debugSystemObjects.GetThreadIdsByIndex(threadIndex, count, null, sysIds))) { throw new ApplicationException("Could not convert thread index " + threadIndex + " to thread ID: " + h); } ClrException clrException = null; if (IsThreadManaged(sysIds[0])) { ClrThread thread = _runtime.Threads.First(t => t.OSThreadId == sysIds[0]); clrException = thread.CurrentException; } return(new EventInformation { Type = eventType, Description = description.ToString(), ProcessId = processId, ThreadId = sysIds[0], ClrException = clrException }); }
public void TestStackTrace() { using DataTarget dt = TestTargets.NestedException.LoadFullDump(); using ClrRuntime runtime = dt.ClrVersions.Single().CreateRuntime(); ClrThread thread = runtime.GetMainThread(); ClrException exception = thread.CurrentException; Assert.NotNull(exception); ImmutableArray <ClrStackFrame> stackTrace = exception.StackTrace; foreach (ClrStackFrame stackFrame in stackTrace) { Assert.Equal(stackFrame.Thread, thread); } }
internal static void TestProperties(ClrRuntime runtime) { ClrThread thread = runtime.GetMainThread(); ClrException ex = thread.CurrentException; Assert.NotNull(ex); ExceptionTestData testData = TestTargets.NestedExceptionData; Assert.Equal(testData.OuterExceptionMessage, ex.Message); if (ex.Type.Name != null) { Assert.Equal(testData.OuterExceptionType, ex.Type.Name); } Assert.NotNull(ex.Inner); }
internal static ExceptionInfo ConvertFrom(ClrException source) { if (source == null) { return(null); } return(new ExceptionInfo { Address = source.Address, HResult = source.HResult, Inner = ConvertFrom(source.Inner), Message = source.Message, Type = source.Type.Name, StackTraceLines = source.StackTrace.Select(x => x.DisplayString).ToList() }); }
private static void DisplayException(ClrException exception, CommandExecutionContext context) { context.WriteLine("Exception object: {0:x16}", exception.Address); context.WriteLine("Exception type: {0}", exception.Type.Name); if (context.TargetType != TargetType.DumpFileNoHeap) { // In no-heap dumps, stuff goes wrong inside DesktopException because some fields can't // be found. It can be fixed with a lot of refactoring (not relying on fields at all and // using offsets instead), but it's probably not such a big deal anyway. var innerException = exception.Inner; context.WriteLine("Message: {0}", exception.GetExceptionMessageSafe()); context.WriteLine("Inner exception: {0}", innerException == null ? "<none>" : String.Format("{0:x16}", innerException.Address)); context.WriteLine("HResult: {0:x}", exception.HResult); } context.WriteLine("Stack trace:"); ClrThreadExtensions.WriteStackTraceToContext(null, exception.StackTrace, context, displayArgumentsAndLocals: false); }
public void DumpAllExceptions(IMDObjectEnum Exceptions) { Dictionary <string, List <ulong> > allExceptions = new Dictionary <string, List <ulong> >(); foreach (var obj in ((MDObjectEnum)Exceptions).List) { ClrException ex = m_heap.GetExceptionObject(obj); if (ex != null) { if (IsInterrupted()) { return; } string key = String.Format("{0}\0{1}\0{2}", ex.Type.Name, ex.Message, DumpStack(ex.StackTrace, m_heap.GetRuntime().PointerSize, true)); if (!allExceptions.ContainsKey(key)) { allExceptions[key] = new List <ulong>(); } allExceptions[key].Add(obj); } } int exCount = 0; int typeCount = 0; foreach (var key in allExceptions.Keys) { typeCount++; exCount += allExceptions[key].Count; Write("{0,8:#,#} of Type: {1}", allExceptions[key].Count, key.Split('\0')[0]); for (int i = 0; i < Math.Min(3, allExceptions[key].Count); i++) { Write(" <link cmd=\"!wpe {0:%p}\">{0:%p}</link>", (allExceptions[key])[i]); } ClrException ex = m_heap.GetExceptionObject((allExceptions[key])[0]); WriteLine(""); WriteLine("Message: {0}", key.Split('\0')[1]); WriteLine("Inner Exception: {0}", ex.Inner == null ? "(none)" : ex.Inner.Type.Name); WriteLine("Stack:"); WriteLine("{0}", key.Split('\0')[2]); WriteLine(""); } WriteLine("{0:#,#} Exceptions in {1:#,#} unique type/stack combinations (duplicate types in similar stacks may be rethrows)", exCount, typeCount); WriteLine(""); }
private void PrintException(ClrException exception) { if (exception != null) { context.WriteLine("Address: {0:X}, Type: {1}, Message: {2}", exception.Address, exception.Type.Name, exception.GetExceptionMessageSafe()); context.WriteLine("Stacktrace:"); foreach (ClrStackFrame frame in exception.StackTrace) { context.WriteLine("{0,-20:x16} {1}!{2}", frame.InstructionPointer, frame.ModuleName, frame.DisplayString); } } }
public void PrintManagedExceptions() { if (context.Runtime != null) { foreach (ClrThread thread in this.context.Runtime.Threads) { ClrException lastException = thread.CurrentException; if (lastException != null) { context.Write("Exception on thread {0} (OS:{1}): ", thread.ManagedThreadId, thread.OSThreadId); this.PrintException(lastException); if (lastException.Inner != null) { this.PrintException(lastException.Inner); } } } } }
public SDClrException(ClrException clrException) { if (clrException != null) { this.Address = clrException.Address; //this.HResult = clrException.HResult; if (this.InnerException != null) { this.InnerException = new SDClrException(clrException.Inner); } this.Message = clrException.GetExceptionMessageSafe(); this.StackTrace = new List <CombinedStackFrame>(); foreach (ClrStackFrame clrFrame in clrException.StackTrace) { this.StackTrace.Add(new CombinedStackFrame(clrFrame)); } } }
private string GetExceptionCallStack(ClrException exception, bool innerException = false) { StringBuilder @string = new StringBuilder(); string innerEx = ""; if (innerException) { @string.Append("Inner exception:\n"); } @string.Append("Exception details:\n"); @string.Append($"{exception.Type.Name}\n"); @string.Append("Exception Message:\n"); @string.Append($"{exception.Message}\n\n"); @string.Append("Exception stack"); @string.Append(GetExceptionStackFrames(exception.StackTrace)); if (exception.Inner != null) { innerEx = GetExceptionCallStack(exception.Inner, true); } @string.Append(innerEx); return(@string.ToString()); }
public void PrintExceptionsObjects() { if (this.context.Heap != null && this.context.Heap.CanWalkHeap) { foreach (var address in this.context.Heap.EnumerateObjectAddresses()) { ClrType type = this.context.Heap.GetObjectType(address); if (type != null) { if (this.context.Heap.GetObjectType(address).IsException) { ClrException exception = this.context.Heap.GetExceptionObject(address); if (exception != null) { context.WriteLine("Address: {0:X}, Type: {1}, Message: {2}", exception.Address, exception.Type.Name, exception.GetExceptionMessageSafe()); context.WriteLine("Stacktrace:"); foreach (ClrStackFrame frame in exception.StackTrace) { context.WriteLine("{0,-20:x16} {1}!{2}", frame.InstructionPointer, frame.ModuleName, frame.DisplayString); } } } } } } else { context.WriteError("no heap information is avaliable"); } }
public static SDClrException ToSDModel(this ClrException clrException) { var model = new SDClrException(); if (clrException != null) { model.Address = clrException.Address; model.Type = clrException.Type.Name; //this.HResult = clrException.HResult; if (model.InnerException != null) { model.InnerException = clrException.Inner.ToSDModel(); } model.Message = clrException.GetExceptionMessageSafe(); foreach (ClrStackFrame clrFrame in clrException.StackTrace) { model.StackTrace.Add(clrFrame.ToSDModel()); } } return(model); }
internal void setInnerException(ClrException inner) { _innerException = inner; }
internal void SetInnerException(ClrException inner) { _innerException = inner; }
public void DumpOnException(uint threadId, EXCEPTION_RECORD ev) { if (ev.ExceptionCode == BREAKPOINT_CODE) { return; } if (ev.ExceptionCode == CLRDBG_NOTIFICATION_EXCEPTION_CODE) { // based on https://social.msdn.microsoft.com/Forums/vstudio/en-US/bca092d4-d2b5-49ef-8bbc-cbce2c67aa89/net-40-firstchance-exception-0x04242420?forum=clr // it's a "notification exception" and can be safely ignored return; } if (ev.ExceptionCode == CTRL_C_EXCEPTION_CODE) { // we will also ignore CTRL+C events return; } // print information about the exception (decode it) ClrException managedException = null; foreach (var clrver in target.ClrVersions) { var runtime = clrver.CreateRuntime(); var thr = runtime.Threads.FirstOrDefault(t => t.OSThreadId == threadId); if (thr != null) { managedException = thr.CurrentException; break; } } var exceptionInfo = string.Format("{0:X}.{1} (\"{2}\")", ev.ExceptionCode, managedException != null ? managedException.Type.Name : "Native", managedException != null ? managedException.Message : "N/A"); PrintTrace("Exception: " + exceptionInfo); if (rgxFilter.IsMatch(exceptionInfo)) { byte[] threadContext = new byte[Native.CONTEXT_SIZE]; target.DataReader.GetThreadContext(threadId, 0, Native.CONTEXT_SIZE, threadContext); IntPtr pev = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(EXCEPTION_RECORD))); Marshal.StructureToPtr(new EXCEPTION_RECORD { ExceptionAddress = ev.ExceptionAddress, ExceptionFlags = ev.ExceptionFlags, ExceptionCode = ev.ExceptionCode, ExceptionRecord = IntPtr.Zero, NumberParameters = ev.NumberParameters, ExceptionInformation = ev.ExceptionInformation }, pev, false); var excpointers = new EXCEPTION_POINTERS { ExceptionRecord = pev, ContextRecord = threadContext }; IntPtr ptr = Marshal.AllocHGlobal(Marshal.SizeOf(excpointers)); Marshal.StructureToPtr(excpointers, ptr, false); var excinfo = new MINIDUMP_EXCEPTION_INFORMATION() { ThreadId = threadId, ClientPointers = false, ExceptionPointers = ptr }; var pexcinfo = Marshal.AllocHGlobal(Marshal.SizeOf(excinfo)); Marshal.StructureToPtr(excinfo, pexcinfo, false); MakeActualDump(pexcinfo); Marshal.FreeHGlobal(pev); Marshal.FreeHGlobal(pexcinfo); Marshal.FreeHGlobal(ptr); } }
static void Main(string[] args) { string dump = string.Empty, dac = string.Empty; bool dso = false; int pid = Convert.ToInt32(args[0]); //if (!TryParseArgs(args, out dump, out dac, out dso)) //{ // Usage(); // return; //} ClrRuntime runtime = CreateRuntime(pid, dump, dac); // Walk each thread in the process. foreach (ClrThread thread in runtime.Threads) { // The ClrRuntime.Threads will also report threads which have recently died, but their // underlying datastructures have not yet been cleaned up. This can potentially be // useful in debugging (!threads displays this information with XXX displayed for their // OS thread id). You cannot walk the stack of these threads though, so we skip them // here. if (!thread.IsAlive) { continue; } Console.WriteLine("Thread {0:X}:", thread.OSThreadId); Console.WriteLine("Stack: {0:X} - {1:X}", thread.StackBase, thread.StackLimit); // Each thread tracks a "last thrown exception". This is the exception object which // !threads prints. If that exception object is present, we will display some basic // exception data here. Note that you can get the stack trace of the exception with // ClrHeapException.StackTrace (we don't do that here). ClrException exception = thread.CurrentException; if (exception != null) { Console.WriteLine("Exception: {0:X} ({1}), HRESULT={2:X}", exception.Address, exception.Type.Name, exception.HResult); } // Walk the stack of the thread and print output similar to !ClrStack. Console.WriteLine(); Console.WriteLine("Managed Callstack:"); foreach (ClrStackFrame frame in thread.StackTrace) { // Note that CLRStackFrame currently only has three pieces of data: stack pointer, // instruction pointer, and frame name (which comes from ToString). Future // versions of this API will allow you to get the type/function/module of the // method (instead of just the name). This is not yet implemented. Console.WriteLine("{0,16:X} {1,16:X} {2}", frame.StackPointer, frame.InstructionPointer, frame.DisplayString); } // Print a !DumpStackObjects equivalent. if (dso) { // We'll need heap data to find objects on the stack. ClrHeap heap = runtime.Heap; // Walk each pointer aligned address on the stack. Note that StackBase/StackLimit // is exactly what they are in the TEB. This means StackBase > StackLimit on AMD64. ulong start = thread.StackBase; ulong stop = thread.StackLimit; // We'll walk these in pointer order. if (start > stop) { ulong tmp = start; start = stop; stop = tmp; } Console.WriteLine(); Console.WriteLine("Stack objects:"); // Walk each pointer aligned address. Ptr is a stack address. for (ulong ptr = start; ptr <= stop; ptr += (ulong)runtime.PointerSize) { // Read the value of this pointer. If we fail to read the memory, break. The // stack region should be in the crash dump. ulong obj; if (!runtime.ReadPointer(ptr, out obj)) { break; } // 003DF2A4 // We check to see if this address is a valid object by simply calling // GetObjectType. If that returns null, it's not an object. ClrType type = heap.GetObjectType(obj); if (type == null) { continue; } // Don't print out free objects as there tends to be a lot of them on // the stack. if (!type.IsFree) { Console.WriteLine("{0,16:X} {1,16:X} {2}", ptr, obj, type.Name); } } } Console.WriteLine(); Console.WriteLine("----------------------------------"); Console.WriteLine(); } }
public MDException(ClrException ex) { m_ex = ex; }