public static extern void RtlUnwindEx(IntPtr TargetFrame, IntPtr TargetIp, ref EXCEPTION_RECORD ExceptionRecord, IntPtr ReturnValue, ref CONTEXT OriginalContext, IntPtr HistoryTable);
public static extern void RtlUnwind(IntPtr TargetFrame, IntPtr TargetIp, ref EXCEPTION_RECORD ExceptionRecord, IntPtr ReturnValue);
void EventCurrentDomainUnhandledException(object sender, UnhandledExceptionEventArgs e) { try { throw (e.ExceptionObject as Exception); } catch (SEHException x) { // Marshal.GetExceptionCode() returns the exception code which was passed // by as the first parameter to RaiseException(). int iExceptionCode = Marshal.GetExceptionCode(); // Get a pointer to the unmanaged EXCEPTION_POINTERS structure. IntPtr pExceptionPointers = Marshal.GetExceptionPointers(); // Convert the unmanaged EXCEPTION_POINTERS structure into its managed version // using Marshal.PtrToStructure(). EXCEPTION_POINTERS exception_pointers = (EXCEPTION_POINTERS)Marshal.PtrToStructure(pExceptionPointers, typeof(EXCEPTION_POINTERS)); // Convert the unmanaged EXCEPTION_RECORD structure into its managed version // using Marshal.PtrToStructure(). EXCEPTION_RECORD exception_record = (EXCEPTION_RECORD)Marshal.PtrToStructure ( exception_pointers.pExceptionRecord, typeof(EXCEPTION_RECORD) ); // Check the exception code. If it is one we recognize, we proceed // to extract our customized exception information, e.i. a pointer // to an MyException structure. if (((UInt32)iExceptionCode == 100) && (exception_record.NumberParameters > 0)) { // The exception_record.ExceptionInformation[] array contains user-defined // data. The first item is a pointer to the unmanaged MySEHExceptionStruct // C++ structure. // We must convert it into a managed version of the MySEHExceptionStruct // structure. MySEHExceptionStruct my_seh_exception_structure = (MySEHExceptionStruct)Marshal.PtrToStructure ( (IntPtr)(exception_record.ExceptionInformation[0]), typeof(MySEHExceptionStruct) ); // Display info on exception. Console.WriteLine("Exception code : {0:D}.", iExceptionCode); Console.WriteLine("Exception Message 1 : {0:S}", my_seh_exception_structure.m_strMessage1); Console.WriteLine("Exception Message 2 : {0:S}", my_seh_exception_structure.m_strMessage2); // It is the responsibility of the recipient of the exception to free // the memory occupied by the unmanaged MySEHExceptionStruct as well // as members of the unmanaged MySEHExceptionStruct which are references // to other memory. We do this by calling Marshal.DestroyStructure(). // // Marshal.DestroyStructure() requires adequate information for the fields // of the target structure to destroy (in the form of MarshalAsAttributes). Marshal.DestroyStructure((IntPtr)(exception_record.ExceptionInformation[0]), typeof(MySEHExceptionStruct)); // Finally, free the unmanaged MySEHExceptionStruct structure itself. Marshal.FreeCoTaskMem((IntPtr)(exception_record.ExceptionInformation[0])); } MessageBox.Show(x.ToString()); } catch (Exception x) { MessageBox.Show(x.ToString()); } }
public static extern void RtlRestoreContext(ref CONTEXT ContextRecord, ref EXCEPTION_RECORD ExceptionRecord);
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); } }