//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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); } }