public void HandleLastChanceException(ExceptionNativeEvent em) { try { this.PyProcess.on_exception_last_chance((Int64)em.Address, (uint)em.ExceptionCode, em); } catch (Exception e) { _pyBoss.PrintError(e, string.Format("'Process' handler for instance '{0}' failed during attempt to call 'on_exception_last_chance()':", _name)); } }
public void HandleNativeDebugEvent(ExceptionNativeEvent em, ref Hashtable numEventsByTarget, ref bool wx86BreakpointReceived) { switch (em.ExceptionCode) { case ExceptionCode.STATUS_WX86_BREAKPOINT: case ExceptionCode.STATUS_BREAKPOINT: if (em.ExceptionCode == ExceptionCode.STATUS_WX86_BREAKPOINT && !wx86BreakpointReceived) { Console.WriteLine(string.Format("WOW64 load breakpoint event.")); wx86BreakpointReceived = true; em.ClearException(); } if (_breakpoints.Contains(em.Address)) { // Get the thread context IntPtr hThread = NativeMethods.OpenThread(ThreadAccess.THREAD_ALL_ACCESS, true, (uint)em.ThreadId); Context context = new Context(_process, hThread); // Suspend all threads //suspended = SuspendAllThreads((int)em.ThreadId); // Save the thread context with the threadId to use it in the EXCEPTION_SINGLE_STEP handler. if (_breakpointInfo.Contains((uint)em.ThreadId)) { _breakpointInfo[(uint)em.ThreadId] = em.Address; } else { _breakpointInfo.Add((uint)em.ThreadId, em.Address); } // Set the trap flag context.SetStepFlag(); // Backup IP by 1 context.BackupIpBy1(); // Process the breakpoint event bool processed = ProcessBreakpointEvent(hThread, (Breakpoint)_breakpoints[em.Address], ref context, ref numEventsByTarget); if (!context.SetContext(hThread)) { Console.WriteLine("Error setting thread context after breakpoint. Error code: " + GetLastError().ToString()); } // Write the original byte back ((Breakpoint)_breakpoints[em.Address]).ClearBreakpoint(); CloseHandle(hThread); // Clear the exception em.ClearException(); } break; case ExceptionCode.STATUS_WX86_SINGLE_STEP: case ExceptionCode.STATUS_SINGLESTEP: // Get the context from the STATUS_BREAKPOINT event if (_breakpointInfo.Contains((uint)em.ThreadId)) { IntPtr bp_addr = (IntPtr)_breakpointInfo[(uint)em.ThreadId]; _breakpointInfo.Remove((uint)em.ThreadId); if (_breakpoints.Contains(bp_addr)) { // Restore the breakpoint try { ((Breakpoint)_breakpoints[bp_addr]).SetBreakpoint(); } catch (Exception e) { Console.WriteLine(string.Format("ERROR: Debugger failed to set breakpoint again after single step.")); } } // Clear the exception em.ClearException(); // Resume all threads //ResumeAllThreads(suspended); //suspended = new List<IntPtr>(0); } else { Console.WriteLine(string.Format("ERROR: Failed to find entry for thread id.")); em.ClearException(); } break; default: //Console.WriteLine(string.Format("\n APPLICATION CRASH: Unhandled native debug event:\nException Code: {0}\nEvent Code: {1}\nAddress: {2}\n", em.ExceptionCode.ToString("X"), em.EventCode.ToString(), em.Address.ToString("X"))); if (em.FirstChance) { // The debugee should be given a chance to handle this exception, but the python code might care to log it. this._process.HandleFirstChanceException(em); } else { // Unhandled last chance exception. Application crashed. // Hand it off to the process handler this._process.HandleLastChanceException(em); } // Clear the exception, only for test purposes. We shouldn't clear this. //em.ClearException(); break; } }