//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public DebuggeeBreakpointError FindErrorBreakpoint(uint id) { // // Search all registered pending breakpoints objects for a bound breakpoint matching the requested id. // LoggingUtils.PrintFunction(); try { foreach (var pending in m_pendingBreakpoints) { // // Check for matching 'error' breakpoints. // int handle = pending.EnumErrorBreakpoints(enum_BP_ERROR_TYPE.BPET_ALL, out IEnumDebugErrorBreakpoints2 enumeratedErrorBreakpoints); if (handle == Constants.E_BP_DELETED) { continue; // Skip any deleted breakpoints. } LoggingUtils.RequireOk(handle); LoggingUtils.RequireOk(enumeratedErrorBreakpoints.GetCount(out uint numErrorBreakpoints)); if (numErrorBreakpoints > 0) { DebuggeeBreakpointError [] errorBreakpoints = new DebuggeeBreakpointError [numErrorBreakpoints]; LoggingUtils.RequireOk(enumeratedErrorBreakpoints.Next(numErrorBreakpoints, errorBreakpoints, numErrorBreakpoints)); for (uint i = 0; i < numErrorBreakpoints; ++i) { if (errorBreakpoints [i] is CLangDebuggeeBreakpointError) { CLangDebuggeeBreakpointError error = errorBreakpoints [i] as CLangDebuggeeBreakpointError; if (error.GdbBreakpoint.ID == id) { return(error); } } else { throw new NotImplementedException("Unrecognised error breakpoint type"); } } } } } catch (Exception e) { LoggingUtils.HandleException(e); } return(null); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int CreateErrorBreakpoint(string errorReason, MiBreakpoint gdbBreakpoint, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext) { // // Create a C-language breakpoint. This is tied to a GDB/MI breakpoint object. // LoggingUtils.PrintFunction(); try { CLangDebuggeeBreakpointError errorBreakpoint = new CLangDebuggeeBreakpointError(m_debugger, m_breakpointManager, this, codeContext, gdbBreakpoint, errorReason); lock (m_errorBreakpoints) { m_errorBreakpoints.Clear(); m_errorBreakpoints.Add(errorBreakpoint); } uint numDebugPrograms = 1; IEnumDebugPrograms2 debugPrograms; IDebugProgram2 [] debugProgramsArray = new IDebugProgram2 [numDebugPrograms]; LoggingUtils.RequireOk(m_breakpointManager.Engine.EnumPrograms(out debugPrograms)); LoggingUtils.RequireOk(debugPrograms.Next(numDebugPrograms, debugProgramsArray, ref numDebugPrograms)); m_breakpointManager.Engine.Broadcast(new DebugEngineEvent.BreakpointError(errorBreakpoint), debugProgramsArray [0], null); return(Constants.S_OK); } catch (Exception e) { LoggingUtils.HandleException(e); return(Constants.E_FAIL); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void RefreshBreakpoint(object breakpoint) { // // Validate breakpoint input type. This function can be used for 'bound' and 'error' objects, so we need to handle this appropriately. // LoggingUtils.PrintFunction(); CLangDebuggeeBreakpointBound boundBreakpoint = null; CLangDebuggeeBreakpointError errorBreakpoint = null; MiBreakpoint gdbBreakpoint; DebuggeeBreakpointResolution resolution; if (breakpoint == null) { throw new ArgumentNullException("breakpoint"); } else if (breakpoint is CLangDebuggeeBreakpointBound) { boundBreakpoint = breakpoint as CLangDebuggeeBreakpointBound; gdbBreakpoint = boundBreakpoint.GdbBreakpoint; IDebugBreakpointResolution2 boundBreakpointResolution; int handle = boundBreakpoint.GetBreakpointResolution(out boundBreakpointResolution); if (handle == Constants.E_BP_DELETED) { return; } LoggingUtils.RequireOk(handle); resolution = (DebuggeeBreakpointResolution)boundBreakpointResolution; } else if (breakpoint is CLangDebuggeeBreakpointError) { errorBreakpoint = breakpoint as CLangDebuggeeBreakpointError; gdbBreakpoint = errorBreakpoint.GdbBreakpoint; IDebugErrorBreakpointResolution2 errorBreakpointResolution; int handle = errorBreakpoint.GetBreakpointResolution(out errorBreakpointResolution); if (handle == Constants.E_BP_DELETED) { return; } resolution = (DebuggeeBreakpointResolution)errorBreakpointResolution; lock (m_errorBreakpoints) { m_errorBreakpoints.Remove(errorBreakpoint); } } else { throw new ArgumentException("breakpoint"); } // // Query breakpoint info/status directly from GDB/MI. // try { string command = string.Format("-break-info {0}", gdbBreakpoint.ID); m_debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord) { if (resultRecord == null) { throw new InvalidOperationException(); } else if (resultRecord.IsError()) { // // GDB/MI breakpoint info request failed. // gdbBreakpoint.Address = MiBreakpoint.Pending; (resolution as DebuggeeBreakpointResolution).CodeContext.Address = new DebuggeeAddress(gdbBreakpoint.Address); errorBreakpoint = new CLangDebuggeeBreakpointError(m_debugger, m_breakpointManager, this, (resolution as DebuggeeBreakpointResolution).CodeContext, gdbBreakpoint, resultRecord.Records [1].Stream); lock (m_errorBreakpoints) { m_errorBreakpoints.Add(errorBreakpoint); } m_debugger.Engine.Broadcast(new DebugEngineEvent.BreakpointError(errorBreakpoint), m_debugger.NativeProgram.DebugProgram, m_debugger.NativeProgram.GetThread(m_debugger.NativeProgram.CurrentThreadId)); } else { // // We've probably got sane breakpoint information back. Update current breakpoint values and re-process. // MiResultValue breakpointData = resultRecord ["BreakpointTable"] [0] ["body"] [0] ["bkpt"] [0]; MiBreakpoint currentGdbBreakpoint = new MiBreakpoint(breakpointData.Values); DebuggeeCodeContext codeContext = (resolution as DebuggeeBreakpointResolution).CodeContext; DebuggeeDocumentContext documentContext = codeContext.DocumentContext; LoggingUtils.RequireOk(CreateBoundBreakpoint(currentGdbBreakpoint, documentContext, codeContext)); } }); } catch (Exception e) { LoggingUtils.HandleException(e); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// private void RefreshBreakpoint (object breakpoint) { // // Validate breakpoint input type. This function can be used for 'bound' and 'error' objects, so we need to handle this appropriately. // LoggingUtils.PrintFunction (); CLangDebuggeeBreakpointBound boundBreakpoint = null; CLangDebuggeeBreakpointError errorBreakpoint = null; MiBreakpoint gdbBreakpoint; DebuggeeBreakpointResolution resolution; if (breakpoint == null) { throw new ArgumentNullException ("breakpoint"); } else if (breakpoint is CLangDebuggeeBreakpointBound) { boundBreakpoint = breakpoint as CLangDebuggeeBreakpointBound; gdbBreakpoint = boundBreakpoint.GdbBreakpoint; IDebugBreakpointResolution2 boundBreakpointResolution; int handle = boundBreakpoint.GetBreakpointResolution (out boundBreakpointResolution); if (handle == Constants.E_BP_DELETED) { return; } LoggingUtils.RequireOk (handle); resolution = (DebuggeeBreakpointResolution) boundBreakpointResolution; } else if (breakpoint is CLangDebuggeeBreakpointError) { errorBreakpoint = breakpoint as CLangDebuggeeBreakpointError; gdbBreakpoint = errorBreakpoint.GdbBreakpoint; IDebugErrorBreakpointResolution2 errorBreakpointResolution; int handle = errorBreakpoint.GetBreakpointResolution (out errorBreakpointResolution); if (handle == Constants.E_BP_DELETED) { return; } resolution = (DebuggeeBreakpointResolution) errorBreakpointResolution; lock (m_errorBreakpoints) { m_errorBreakpoints.Remove (errorBreakpoint); } } else { throw new ArgumentException ("breakpoint"); } // // Query breakpoint info/status directly from GDB/MI. // try { string command = string.Format ("-break-info {0}", gdbBreakpoint.ID); m_debugger.GdbClient.SendCommand (command, delegate (MiResultRecord resultRecord) { if (resultRecord == null) { throw new InvalidOperationException (); } else if (resultRecord.IsError ()) { // // GDB/MI breakpoint info request failed. // gdbBreakpoint.Address = MiBreakpoint.Pending; (resolution as DebuggeeBreakpointResolution).CodeContext.Address = new DebuggeeAddress (gdbBreakpoint.Address); errorBreakpoint = new CLangDebuggeeBreakpointError (m_debugger, m_breakpointManager, this, (resolution as DebuggeeBreakpointResolution).CodeContext, gdbBreakpoint, resultRecord.Records [1].Stream); lock (m_errorBreakpoints) { m_errorBreakpoints.Add (errorBreakpoint); } m_debugger.Engine.Broadcast (new DebugEngineEvent.BreakpointError (errorBreakpoint), m_debugger.NativeProgram.DebugProgram, m_debugger.NativeProgram.GetThread (m_debugger.NativeProgram.CurrentThreadId)); } else { // // We've probably got sane breakpoint information back. Update current breakpoint values and re-process. // MiResultValue breakpointData = resultRecord ["BreakpointTable"] [0] ["body"] [0] ["bkpt"] [0]; MiBreakpoint currentGdbBreakpoint = new MiBreakpoint (breakpointData.Values); DebuggeeCodeContext codeContext = (resolution as DebuggeeBreakpointResolution).CodeContext; DebuggeeDocumentContext documentContext = codeContext.DocumentContext; LoggingUtils.RequireOk (CreateBoundBreakpoint (currentGdbBreakpoint, documentContext, codeContext)); } }); } catch (Exception e) { LoggingUtils.HandleException (e); } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// public int CreateErrorBreakpoint (string errorReason, MiBreakpoint gdbBreakpoint, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext) { // // Create a C-language breakpoint. This is tied to a GDB/MI breakpoint object. // LoggingUtils.PrintFunction (); try { CLangDebuggeeBreakpointError errorBreakpoint = new CLangDebuggeeBreakpointError (m_debugger, m_breakpointManager, this, codeContext, gdbBreakpoint, errorReason); lock (m_errorBreakpoints) { m_errorBreakpoints.Clear (); m_errorBreakpoints.Add (errorBreakpoint); } uint numDebugPrograms = 1; IEnumDebugPrograms2 debugPrograms; IDebugProgram2 [] debugProgramsArray = new IDebugProgram2 [numDebugPrograms]; LoggingUtils.RequireOk (m_breakpointManager.Engine.EnumPrograms (out debugPrograms)); LoggingUtils.RequireOk (debugPrograms.Next (numDebugPrograms, debugProgramsArray, ref numDebugPrograms)); m_breakpointManager.Engine.Broadcast (new DebugEngineEvent.BreakpointError (errorBreakpoint), debugProgramsArray [0], null); return Constants.S_OK; } catch (Exception e) { LoggingUtils.HandleException (e); return Constants.E_FAIL; } }