예제 #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeCodeContext(DebugEngine engine, DebuggeeDocumentContext documentContext, DebuggeeAddress address)
        {
            m_engine = engine;

            m_documentContext = documentContext ?? throw new ArgumentNullException(nameof(documentContext));

            m_address = address ?? throw new ArgumentNullException(nameof(address));
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int CreateBoundBreakpoint(string location, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
        {
            //
            // Register a new GDB breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                if (m_breakpointRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_TYPE.BPT_DATA)
                {
                    throw new NotImplementedException();
                }

                m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    string command = string.Format("-break-insert -f {0} {1}", ((m_breakpointEnabled) ? "" : "-d"), PathUtils.SantiseWindowsPath(location));

                    debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        if (resultRecord != null)
                        {
                            if (resultRecord.IsError())
                            {
                                string errorReason = "<unknown error>";

                                if (resultRecord.HasField("msg"))
                                {
                                    errorReason = resultRecord ["msg"] [0].GetString();
                                }

                                LoggingUtils.RequireOk(CreateErrorBreakpoint(errorReason, documentContext, codeContext));
                            }
                            else
                            {
                                MiResultValue breakpointData = resultRecord ["bkpt"] [0];

                                MiBreakpoint breakpoint = new MiBreakpoint(breakpointData.Values);

                                LoggingUtils.RequireOk(CreateBoundBreakpoint(breakpoint, documentContext, codeContext));
                            }
                        }
                    });
                });

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int EvaluateBreakpointLocation(out DebuggeeDocumentContext documentContext, out DebuggeeCodeContext codeContext, out string location)
        {
            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(base.EvaluateBreakpointLocation(out documentContext, out codeContext, out location));

                /*switch (m_breakpointRequestInfo.bpLocation.bpLocationType)
                 * {
                 * case (uint) enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE:
                 * {
                 *  codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation (m_debugger, location);
                 *
                 *  if (codeContext == null)
                 *  {
                 *    throw new InvalidOperationException ();
                 *  }
                 *
                 *  documentContext = codeContext.DocumentContext;
                 *
                 *  if (documentContext == null)
                 *  {
                 *    throw new InvalidOperationException ();
                 *  }
                 *
                 *  break;
                 * }
                 *
                 * default:
                 * {
                 *  break;
                 * }
                 * }*/

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                documentContext = null;

                codeContext = null;

                location = string.Empty;

                return(Constants.E_FAIL);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public override int EvaluateBreakpointLocation (out DebuggeeDocumentContext documentContext, out DebuggeeCodeContext codeContext, out string location)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        LoggingUtils.RequireOk (base.EvaluateBreakpointLocation (out documentContext, out codeContext, out location));

        /*switch (m_breakpointRequestInfo.bpLocation.bpLocationType)
        {
          case (uint) enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE:
          {
            codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation (m_debugger, location);

            if (codeContext == null)
            {
              throw new InvalidOperationException ();
            }

            documentContext = codeContext.DocumentContext;

            if (documentContext == null)
            {
              throw new InvalidOperationException ();
            }

            break;
          }

          default:
          {
            break;
          }
        }*/

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        documentContext = null;

        codeContext = null;

        location = string.Empty;

        return Constants.E_FAIL;
      }
    }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeCodeContext(DebugEngine engine, DebuggeeDocumentContext documentContext, DebuggeeAddress address)
        {
            if (documentContext == null)
            {
                throw new ArgumentNullException("documentContext");
            }

            if (address == null)
            {
                throw new ArgumentNullException("address");
            }

            m_engine = engine;

            m_documentContext = documentContext;

            m_address = address;
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int EnumCodeContexts (IDebugDocumentPosition2 pDocPos, out IEnumDebugCodeContexts2 ppEnum)
    {
      // 
      // Enumerates the code contexts for a given position in a source file.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        string fileName;

        TEXT_POSITION [] startPos = new TEXT_POSITION [1];

        TEXT_POSITION [] endPos = new TEXT_POSITION [1];

        LoggingUtils.RequireOk (pDocPos.GetFileName (out fileName));

        LoggingUtils.RequireOk (pDocPos.GetRange (startPos, endPos));

        DebuggeeDocumentContext documentContext = new DebuggeeDocumentContext (m_debugger.Engine, fileName, startPos [0], endPos [0]);

        CLangDebuggeeCodeContext codeContext = CLangDebuggeeCodeContext.GetCodeContextForDocumentContext (m_debugger, documentContext);

        if (codeContext == null)
        {
          throw new InvalidOperationException ("Failed evaluating code-context for location.");
        }

        CLangDebuggeeCodeContext [] codeContexts = new CLangDebuggeeCodeContext [] { codeContext };

        ppEnum = new DebuggeeCodeContext.Enumerator (codeContexts);

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        ppEnum = null;

        return Constants.E_FAIL;
      }
    }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeStackFrame(DebugEngine engine, DebuggeeThread thread, string frameName)
        {
            m_debugEngine = engine;

            m_thread = thread;

            m_codeContext = null;

            m_documentContext = null;

            m_property = new DebuggeeProperty(engine, this, frameName, string.Empty);

            m_stackRegisters = new ConcurrentDictionary <string, DebuggeeProperty> ();

            m_stackArguments = new ConcurrentDictionary <string, DebuggeeProperty> ();

            m_stackLocals = new ConcurrentDictionary <string, DebuggeeProperty> ();

            m_customExpressions = new ConcurrentDictionary <string, DebuggeeProperty> ();
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public virtual int CreateErrorBreakpoint(string errorReason, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
        {
            //
            // Create and broadcast a generic (non language-specific) errored breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                DebuggeeBreakpointError errorBreakpoint = new DebuggeeBreakpointError(m_breakpointManager, this, codeContext, errorReason);

                lock (m_errorBreakpoints)
                {
                    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);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugPendingBreakpoint2 Members

        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public virtual int Bind()
        {
            //
            // Binds this pending breakpoint to one or more code locations.
            //

            LoggingUtils.PrintFunction();

            DebuggeeDocumentContext documentContext = null;

            DebuggeeCodeContext codeContext = null;

            string bindLocation = string.Empty;

            try
            {
                ClearErrorBreakpoints();

                if (m_breakpointDeleted)
                {
                    return(Constants.E_BP_DELETED);
                }

                LoggingUtils.RequireOk(EvaluateBreakpointLocation(out documentContext, out codeContext, out bindLocation));

                LoggingUtils.RequireOk(CreateBoundBreakpoint(bindLocation, documentContext, codeContext));

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public virtual int EvaluateBreakpointLocation(out DebuggeeDocumentContext documentContext, out DebuggeeCodeContext codeContext, out string location)
        {
            LoggingUtils.PrintFunction();

            documentContext = null;

            codeContext = null;

            location = string.Empty;

            try
            {
                switch (m_breakpointRequestInfo.bpLocation.bpLocationType)
                {
                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FILE_LINE:
                {
                    //
                    // Specifies the location type of the breakpoint as a line of source code.
                    //

                    string fileName;

                    IDebugDocumentPosition2 documentPostion = (IDebugDocumentPosition2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember2);

                    LoggingUtils.RequireOk(documentPostion.GetFileName(out fileName));

                    bool fileInCurrentProject = true; // TODO

                    if (File.Exists(fileName) && fileInCurrentProject)
                    {
                        TEXT_POSITION [] startPos = new TEXT_POSITION [1];

                        TEXT_POSITION [] endPos = new TEXT_POSITION [1];

                        LoggingUtils.RequireOk(documentPostion.GetRange(startPos, endPos));

                        documentContext = new DebuggeeDocumentContext(m_breakpointManager.Engine, fileName, startPos [0], endPos [0]);

                        location = string.Format("\"{0}:{1}\"", fileName, startPos [0].dwLine + 1);
                    }
                    else
                    {
                        throw new NotImplementedException();
                    }

                    break;
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_FUNC_OFFSET:
                {
                    //
                    // Specifies the location type of the breakpoint as a code function offset.
                    //

                    string function = string.Empty;

                    IDebugFunctionPosition2 functionPosition = (IDebugFunctionPosition2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember2);

                    TEXT_POSITION [] textPos = new TEXT_POSITION [1];

                    LoggingUtils.RequireOk(functionPosition.GetFunctionName(out function));

                    LoggingUtils.RequireOk(functionPosition.GetOffset(textPos));

                    if (!string.IsNullOrEmpty(function))
                    {
                        location = function;
                    }

                    break;
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_CONTEXT:
                {
                    //
                    // Specifies the location type of the breakpoint as a code context.
                    //

                    codeContext = ((IDebugCodeContext2)Marshal.GetObjectForIUnknown(m_breakpointRequestInfo.bpLocation.unionmember1)) as DebuggeeCodeContext;

                    if (codeContext != null)
                    {
                        location = codeContext.Address.ToString();
                    }

                    break;
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_STRING:
                {
                    //
                    // Specifies the location type of the breakpoint as a code string.
                    //

                    throw new NotImplementedException();
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_CODE_ADDRESS:
                {
                    //
                    // Specifies the location type of the breakpoint as a code address.
                    //

                    string address = Marshal.PtrToStringBSTR(m_breakpointRequestInfo.bpLocation.unionmember4);

                    if (!string.IsNullOrEmpty(address))
                    {
                        location = address;
                    }

                    break;
                }

                case (uint)enum_BP_LOCATION_TYPE.BPLT_DATA_STRING:
                {
                    //
                    // Specifies the location type of the breakpoint as a data string.
                    //

                    string dataExpression = Marshal.PtrToStringBSTR(m_breakpointRequestInfo.bpLocation.unionmember3);

                    if (!string.IsNullOrEmpty(dataExpression))
                    {
                        location = dataExpression;
                    }

                    break;
                }

                default:
                {
                    break;
                }
                }

                return(Constants.S_OK);
            }
            catch (NotImplementedException e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_NOTIMPL);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
예제 #11
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static CLangDebuggeeCodeContext GetCodeContextForDocumentContext(CLangDebugger debugger, DebuggeeDocumentContext documentContext)
        {
            LoggingUtils.PrintFunction();

            string fileName;

            TEXT_POSITION [] startOffset = new TEXT_POSITION [1];

            TEXT_POSITION [] endOffset = new TEXT_POSITION [1];

            LoggingUtils.RequireOk(documentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out fileName));

            LoggingUtils.RequireOk(documentContext.GetStatementRange(startOffset, endOffset));

            string location = string.Format("\"{0}:{1}\"", fileName, startOffset [0].dwLine + 1);

            return(GetCodeContextForLocation(debugger, location));
        }
예제 #12
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public CLangDebuggeeCodeContext(CLangDebugger debugger, DebuggeeAddress address, DebuggeeDocumentContext documentContext)
            : base(debugger.Engine, documentContext, address)
        {
            m_debugger = debugger;

            try
            {
                string command = string.Format("-interpreter-exec console \"info symbol {0}\"", m_address.ToString());

                MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand(command);

                MiResultRecord.RequireOk(resultRecord, command);

                string pattern = "(?<symbol>.+)( [\\+] (?<offset>[0-9]+))? (in section (?<section>[^ ]+) of) (?<module>.+)";

                Regex regExMatcher = new Regex(pattern, RegexOptions.IgnoreCase);

                foreach (MiStreamRecord record in resultRecord.Records)
                {
                    if (!record.Stream.StartsWith("No symbol"))
                    {
                        continue; // early rejection.
                    }

                    StringBuilder sanitisedStream = new StringBuilder(record.Stream);

                    sanitisedStream.Length -= 2; // Strip trailing "\\n"

                    Match regExLineMatch = regExMatcher.Match(sanitisedStream.ToString());

                    if (regExLineMatch.Success)
                    {
                        string symbol = regExLineMatch.Result("${symbol}");

                        string offset = regExLineMatch.Result("${offset}");

                        string section = regExLineMatch.Result("${section}");

                        string module = regExLineMatch.Result("${module}");

                        ulong addressOffset = 0ul;

                        ulong.TryParse(offset, out addressOffset);

                        m_symbolName = symbol;

                        m_symbolOffset = addressOffset.ToString();

                        //string moduleFile = Path.GetFileName (module);

                        //CLangDebuggeeModule module = m_debugger.NativeProgram.GetModule (moduleFile);

                        //MODULE_INFO [] moduleArray = new MODULE_INFO [1];

                        //LoggingUtils.RequireOk (module.GetInfo (enum_MODULE_INFO_FIELDS.MIF_URL, moduleArray));

                        //infoArray [0].bstrModuleUrl = moduleArray [0].m_bstrUrl;

                        m_symbolModule = PathUtils.ConvertPathMingwToWindows(module);
                    }
                }
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    private void GetInfoFromCurrentLevel (MiResultValueTuple frameTuple)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        if (frameTuple == null)
        {
          throw new ArgumentNullException ("frameTuple");
        }

        if (frameTuple.HasField ("level"))
        {
          m_stackLevel = frameTuple ["level"] [0].GetUnsignedInt ();
        }

        // 
        // Discover the function or shared library location.
        // 

        if (frameTuple.HasField ("addr"))
        {
          m_locationAddress = new DebuggeeAddress (frameTuple ["addr"] [0].GetString ());
        }
        else
        {
          m_locationAddress = new DebuggeeAddress ("0x0");
        }

        if (frameTuple.HasField ("func"))
        {
          m_locationFunction = frameTuple ["func"] [0].GetString ();
        }
        else
        {
          m_locationFunction = "??";
        }

        m_locationIsSymbolicated = !(m_locationFunction.Equals ("??"));

        if (frameTuple.HasField ("from"))
        {
          m_locationModule = Path.GetFileName (frameTuple ["from"] [0].GetString ());
        }
        else
        {
          m_locationModule = string.Empty;
        }

        // 
        // Generate code and document contexts for this frame location.
        // 

        if (frameTuple.HasField ("fullname") && frameTuple.HasField ("line"))
        {
          // 
          // If the symbol table isn't yet loaded, we'll need to specify exactly the location of this stack frame.
          // 

          TEXT_POSITION [] textPositions = new TEXT_POSITION [2];

          textPositions [0].dwLine = frameTuple ["line"] [0].GetUnsignedInt () - 1;

          textPositions [0].dwColumn = 0;

          textPositions [1].dwLine = textPositions [0].dwLine;

          textPositions [1].dwColumn = textPositions [0].dwColumn;

          string filename = PathUtils.ConvertPathCygwinToWindows (frameTuple ["fullname"] [0].GetString ());

          m_documentContext = new DebuggeeDocumentContext (m_debugger.Engine, filename, textPositions [0], textPositions [1]);

          m_codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation (m_debugger, m_locationAddress.ToString ());

          if (m_codeContext == null)
          {
            throw new InvalidOperationException ();
          }
        }
        else
        {
          m_codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation (m_debugger, m_locationAddress.ToString ());

          m_documentContext = (m_codeContext != null) ? m_codeContext.DocumentContext : null;
        }
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);
      }
    }
예제 #14
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public static CLangDebuggeeCodeContext GetCodeContextForLocation(CLangDebugger debugger, string location)
        {
            LoggingUtils.PrintFunction();

            try
            {
                if (string.IsNullOrEmpty(location))
                {
                    throw new ArgumentNullException("location");
                }

                if (location.StartsWith("0x"))
                {
                    location = "*" + location;
                }
                else if (location.StartsWith("\""))
                {
                    location = location.Replace("\\", "/");

                    location = location.Replace("\"", "\\\""); // required to escape the nested string.
                }

                string command = string.Format("-interpreter-exec console \"info line {0}\"", location);

                MiResultRecord resultRecord = debugger.GdbClient.SendSyncCommand(command);

                MiResultRecord.RequireOk(resultRecord, command);

                string pattern = "Line (?<line>[0-9]+) of ([\\]*\"(?<file>.+)[\\]*[\"]+) starts at address (?<startaddr>[^ ]+) (?<startsym>[^+]+[+]?[0-9]*[>]?) (but contains no code|and ends at (?<endaddr>[^ ]+) (?<endsym>[^+]+[+]?[0-9]*[>]?)?)";

                pattern = pattern.Replace("\\", "\\\\");

                Regex regExMatcher = new Regex(pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);

                foreach (MiStreamRecord record in resultRecord.Records)
                {
                    if (!record.Stream.StartsWith("Line"))
                    {
                        continue; // early rejection.
                    }

                    StringBuilder sanitisedStream = new StringBuilder(record.Stream);

                    sanitisedStream.Replace("\\\"", "\"");

                    sanitisedStream.Replace("\\\\", "\\");

                    Match regExLineMatch = regExMatcher.Match(sanitisedStream.ToString());

                    if (regExLineMatch.Success)
                    {
                        string line = regExLineMatch.Result("${line}");

                        string file = regExLineMatch.Result("${file}");

                        string startaddr = regExLineMatch.Result("${startaddr}");

                        string startsym = regExLineMatch.Result("${startsym}");

                        string endaddr = regExLineMatch.Result("${endaddr}");

                        string endsym = regExLineMatch.Result("${endsym}");

                        TEXT_POSITION [] documentPositions = new TEXT_POSITION [2];

                        documentPositions [0].dwLine = uint.Parse(line) - 1;

                        documentPositions [0].dwColumn = 0;

                        documentPositions [1].dwLine = documentPositions [0].dwLine;

                        documentPositions [1].dwColumn = uint.MaxValue;

                        DebuggeeAddress startAddress = new DebuggeeAddress(startaddr);

                        DebuggeeDocumentContext documentContext = new DebuggeeDocumentContext(debugger.Engine, file, documentPositions [0], documentPositions [1]);

                        CLangDebuggeeCodeContext codeContext = new CLangDebuggeeCodeContext(debugger, startAddress, documentContext);

                        documentContext.SetCodeContext(codeContext);

                        return(codeContext);
                    }
                }
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);
            }

            return(null);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        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 override int CreateBoundBreakpoint (string location, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
    {
      // 
      // Register a new GDB breakpoint.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        if (m_breakpointRequestInfo.bpLocation.bpLocationType == (uint)enum_BP_TYPE.BPT_DATA)
        {
          throw new NotImplementedException ();
        }

        m_debugger.RunInterruptOperation (delegate (CLangDebugger debugger)
        {
          string command = string.Format ("-break-insert -f {0} {1}", ((m_breakpointEnabled) ? "" : "-d"), PathUtils.SantiseWindowsPath (location));

          debugger.GdbClient.SendCommand (command, delegate (MiResultRecord resultRecord)
          {
            if (resultRecord != null)
            {
              if (resultRecord.IsError ())
              {
                string errorReason = "<unknown error>";

                if (resultRecord.HasField ("msg"))
                {
                  errorReason = resultRecord ["msg"] [0].GetString ();
                }

                LoggingUtils.RequireOk (CreateErrorBreakpoint (errorReason, documentContext, codeContext));
              }
              else
              {
                MiResultValue breakpointData = resultRecord ["bkpt"] [0];

                MiBreakpoint breakpoint = new MiBreakpoint (breakpointData.Values);

                LoggingUtils.RequireOk (CreateBoundBreakpoint (breakpoint, documentContext, codeContext));
              }
            }
          });
        });

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        return Constants.E_FAIL;
      }
    }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int CreateBoundBreakpoint(MiBreakpoint breakpoint, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
        {
            LoggingUtils.PrintFunction();

            try
            {
                if (breakpoint == null)
                {
                    throw new ArgumentNullException("breakpoint");
                }

                if (breakpoint.IsPending())
                {
                    //
                    // Address can't be satisfied. Unsatisfied likely indicates the modules or symbols associated with the context aren't loaded, yet.
                    //

                    DebuggeeAddress pendingAddress = new DebuggeeAddress(MiBreakpoint.Pending);

                    DebuggeeCodeContext pendingContext = new CLangDebuggeeCodeContext(m_debugger, pendingAddress, documentContext);

                    LoggingUtils.RequireOk(CreateErrorBreakpoint("Additional library symbols required.", breakpoint, documentContext, pendingContext));
                }
                else if (breakpoint.IsMultiple())
                {
                    //
                    // Breakpoint satisfied to multiple locations, no single memory address available.
                    //

                    CLangDebuggeeBreakpointBound boundBreakpoint = new CLangDebuggeeBreakpointBound(m_debugger, m_breakpointManager, this, codeContext, breakpoint);

                    lock (m_boundBreakpoints)
                    {
                        m_boundBreakpoints.Clear();

                        m_boundBreakpoints.Add(boundBreakpoint);
                    }

                    m_debugger.Engine.Broadcast(new DebugEngineEvent.BreakpointBound(this, boundBreakpoint), m_debugger.NativeProgram.DebugProgram, m_debugger.NativeProgram.GetThread(m_debugger.NativeProgram.CurrentThreadId));
                }
                else
                {
                    //
                    // Address satisfied, and the breakpoint is legitimately bound.
                    //

                    DebuggeeAddress boundAddress = new DebuggeeAddress(breakpoint.Address);

                    DebuggeeCodeContext addressContext = new CLangDebuggeeCodeContext(m_debugger, boundAddress, documentContext);

                    CLangDebuggeeBreakpointBound boundBreakpoint = new CLangDebuggeeBreakpointBound(m_debugger, m_breakpointManager, this, addressContext, breakpoint);

                    lock (m_boundBreakpoints)
                    {
                        m_boundBreakpoints.Clear();

                        m_boundBreakpoints.Add(boundBreakpoint);
                    }

                    m_debugger.Engine.Broadcast(new DebugEngineEvent.BreakpointBound(this, boundBreakpoint), m_debugger.NativeProgram.DebugProgram, m_debugger.NativeProgram.GetThread(m_debugger.NativeProgram.CurrentThreadId));
                }

                return(Constants.S_OK);
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

                return(Constants.E_FAIL);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public CLangDebuggeeCodeContext (CLangDebugger debugger, DebuggeeAddress address, DebuggeeDocumentContext documentContext)
      : base (debugger.Engine, documentContext, address)
    {
      m_debugger = debugger;

      try
      {
        string command = string.Format ("-interpreter-exec console \"info symbol {0}\"", m_address.ToString ());

        MiResultRecord resultRecord = m_debugger.GdbClient.SendSyncCommand (command);

        MiResultRecord.RequireOk (resultRecord, command);

        string pattern = "(?<symbol>.+)( [\\+] (?<offset>[0-9]+))? (in section (?<section>[^ ]+) of) (?<module>.+)";

        Regex regExMatcher = new Regex (pattern, RegexOptions.IgnoreCase);

        foreach (MiStreamRecord record in resultRecord.Records)
        {
          if (!record.Stream.StartsWith ("No symbol"))
          {
            continue; // early rejection.
          }

          StringBuilder sanitisedStream = new StringBuilder (record.Stream);

          sanitisedStream.Length -= 2; // Strip trailing "\\n"

          Match regExLineMatch = regExMatcher.Match (sanitisedStream.ToString ());

          if (regExLineMatch.Success)
          {
            string symbol = regExLineMatch.Result ("${symbol}");

            string offset = regExLineMatch.Result ("${offset}");

            string section = regExLineMatch.Result ("${section}");

            string module = regExLineMatch.Result ("${module}");

            ulong addressOffset = 0ul;

            ulong.TryParse (offset, out addressOffset);

            m_symbolName = symbol;

            m_symbolOffset = addressOffset.ToString ();

            //string moduleFile = Path.GetFileName (module);

            //CLangDebuggeeModule module = m_debugger.NativeProgram.GetModule (moduleFile);

            //MODULE_INFO [] moduleArray = new MODULE_INFO [1];

            //LoggingUtils.RequireOk (module.GetInfo (enum_MODULE_INFO_FIELDS.MIF_URL, moduleArray));

            //infoArray [0].bstrModuleUrl = moduleArray [0].m_bstrUrl;

            m_symbolModule = PathUtils.ConvertPathMingwToWindows (module);
          }
        }
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);
      }
    }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public virtual int CreateBoundBreakpoint(string location, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
        {
            LoggingUtils.PrintFunction();

            throw new NotImplementedException();
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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

    public int CreateBoundBreakpoint (MiBreakpoint breakpoint, DebuggeeDocumentContext documentContext, DebuggeeCodeContext codeContext)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        if (breakpoint == null)
        {
          throw new ArgumentNullException ("breakpoint");
        }

        if (breakpoint.IsPending ())
        {
          // 
          // Address can't be satisfied. Unsatisfied likely indicates the modules or symbols associated with the context aren't loaded, yet.
          // 

          DebuggeeAddress pendingAddress = new DebuggeeAddress (MiBreakpoint.Pending);

          DebuggeeCodeContext pendingContext = new CLangDebuggeeCodeContext (m_debugger, pendingAddress, documentContext);

          LoggingUtils.RequireOk (CreateErrorBreakpoint ("Additional library symbols required.", breakpoint, documentContext, pendingContext));
        }
        else if (breakpoint.IsMultiple ())
        {
          // 
          // Breakpoint satisfied to multiple locations, no single memory address available.
          // 

          CLangDebuggeeBreakpointBound boundBreakpoint = new CLangDebuggeeBreakpointBound (m_debugger, m_breakpointManager, this, codeContext, breakpoint);

          lock (m_boundBreakpoints)
          {
            m_boundBreakpoints.Clear ();

            m_boundBreakpoints.Add (boundBreakpoint);
          }

          m_debugger.Engine.Broadcast (new DebugEngineEvent.BreakpointBound (this, boundBreakpoint), m_debugger.NativeProgram.DebugProgram, m_debugger.NativeProgram.GetThread (m_debugger.NativeProgram.CurrentThreadId));
        }
        else
        {
          // 
          // Address satisfied, and the breakpoint is legitimately bound.
          // 

          DebuggeeAddress boundAddress = new DebuggeeAddress (breakpoint.Address);

          DebuggeeCodeContext addressContext = new CLangDebuggeeCodeContext (m_debugger, boundAddress, documentContext);

          CLangDebuggeeBreakpointBound boundBreakpoint = new CLangDebuggeeBreakpointBound (m_debugger, m_breakpointManager, this, addressContext, breakpoint);

          lock (m_boundBreakpoints)
          {
            m_boundBreakpoints.Clear ();

            m_boundBreakpoints.Add (boundBreakpoint);
          }

          m_debugger.Engine.Broadcast (new DebugEngineEvent.BreakpointBound (this, boundBreakpoint), m_debugger.NativeProgram.DebugProgram, m_debugger.NativeProgram.GetThread (m_debugger.NativeProgram.CurrentThreadId));
        }

        return Constants.S_OK;
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);

        return Constants.E_FAIL;
      }
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static CLangDebuggeeCodeContext GetCodeContextForLocation (CLangDebugger debugger, string location)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        if (string.IsNullOrEmpty (location))
        {
          throw new ArgumentNullException ("location");
        }

        if (location.StartsWith ("0x"))
        {
          location = "*" + location;
        }
        else if (location.StartsWith ("\""))
        {
          location = location.Replace ("\\", "/");

          location = location.Replace ("\"", "\\\""); // required to escape the nested string.
        }

        string command = string.Format ("-interpreter-exec console \"info line {0}\"", location);

        MiResultRecord resultRecord = debugger.GdbClient.SendSyncCommand (command);

        MiResultRecord.RequireOk (resultRecord, command);

        string pattern = "Line (?<line>[0-9]+) of ([\\]*\"(?<file>.+)[\\]*[\"]+) starts at address (?<startaddr>[^ ]+) (?<startsym>[^+]+[+]?[0-9]*[>]?) (but contains no code|and ends at (?<endaddr>[^ ]+) (?<endsym>[^+]+[+]?[0-9]*[>]?)?)";

        pattern = pattern.Replace ("\\", "\\\\");

        Regex regExMatcher = new Regex (pattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);

        foreach (MiStreamRecord record in resultRecord.Records)
        {
          if (!record.Stream.StartsWith ("Line"))
          {
            continue; // early rejection.
          }

          StringBuilder sanitisedStream = new StringBuilder (record.Stream);

          sanitisedStream.Replace ("\\\"", "\"");

          sanitisedStream.Replace ("\\\\", "\\");

          Match regExLineMatch = regExMatcher.Match (sanitisedStream.ToString ());

          if (regExLineMatch.Success)
          {
            string line = regExLineMatch.Result ("${line}");

            string file = regExLineMatch.Result ("${file}");

            string startaddr = regExLineMatch.Result ("${startaddr}");

            string startsym = regExLineMatch.Result ("${startsym}");

            string endaddr = regExLineMatch.Result ("${endaddr}");

            string endsym = regExLineMatch.Result ("${endsym}");

            TEXT_POSITION [] documentPositions = new TEXT_POSITION [2];

            documentPositions [0].dwLine = uint.Parse (line) - 1;

            documentPositions [0].dwColumn = 0;

            documentPositions [1].dwLine = documentPositions [0].dwLine;

            documentPositions [1].dwColumn = uint.MaxValue;

            DebuggeeAddress startAddress = new DebuggeeAddress (startaddr);

            DebuggeeDocumentContext documentContext = new DebuggeeDocumentContext (debugger.Engine, file, documentPositions [0], documentPositions [1]);

            CLangDebuggeeCodeContext codeContext = new CLangDebuggeeCodeContext (debugger, startAddress, documentContext);

            documentContext.SetCodeContext (codeContext);

            return codeContext;
          }
        }
      }
      catch (Exception e)
      {
        LoggingUtils.HandleException (e);
      }

      return null;
    }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public static CLangDebuggeeCodeContext GetCodeContextForDocumentContext (CLangDebugger debugger, DebuggeeDocumentContext documentContext)
    {
      LoggingUtils.PrintFunction ();

      string fileName;

      TEXT_POSITION [] startOffset = new TEXT_POSITION [1];

      TEXT_POSITION [] endOffset = new TEXT_POSITION [1];

      LoggingUtils.RequireOk (documentContext.GetName (enum_GETNAME_TYPE.GN_FILENAME, out fileName));

      LoggingUtils.RequireOk (documentContext.GetStatementRange (startOffset, endOffset));

      string location = string.Format ("\"{0}:{1}\"", fileName, startOffset [0].dwLine + 1);

      return GetCodeContextForLocation (debugger, location);
    }
예제 #24
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void GetInfoFromCurrentLevel(MiResultValueTuple frameTuple)
        {
            LoggingUtils.PrintFunction();

            try
            {
                if (frameTuple == null)
                {
                    throw new ArgumentNullException("frameTuple");
                }

                if (frameTuple.HasField("level"))
                {
                    m_stackLevel = frameTuple ["level"] [0].GetUnsignedInt();
                }

                //
                // Discover the function or shared library location.
                //

                if (frameTuple.HasField("addr"))
                {
                    m_locationAddress = new DebuggeeAddress(frameTuple ["addr"] [0].GetString());
                }
                else
                {
                    m_locationAddress = new DebuggeeAddress("0x0");
                }

                if (frameTuple.HasField("func"))
                {
                    m_locationFunction = frameTuple ["func"] [0].GetString();
                }
                else
                {
                    m_locationFunction = "??";
                }

                m_locationIsSymbolicated = !(m_locationFunction.Equals("??"));

                if (frameTuple.HasField("from"))
                {
                    m_locationModule = Path.GetFileName(frameTuple ["from"] [0].GetString());
                }
                else
                {
                    m_locationModule = string.Empty;
                }

                //
                // Generate code and document contexts for this frame location.
                //

                if (frameTuple.HasField("fullname") && frameTuple.HasField("line"))
                {
                    //
                    // If the symbol table isn't yet loaded, we'll need to specify exactly the location of this stack frame.
                    //

                    TEXT_POSITION [] textPositions = new TEXT_POSITION [2];

                    textPositions [0].dwLine = frameTuple ["line"] [0].GetUnsignedInt() - 1;

                    textPositions [0].dwColumn = 0;

                    textPositions [1].dwLine = textPositions [0].dwLine;

                    textPositions [1].dwColumn = textPositions [0].dwColumn;

                    string filename = PathUtils.ConvertPathCygwinToWindows(frameTuple ["fullname"] [0].GetString());

                    m_documentContext = new DebuggeeDocumentContext(m_debugger.Engine, filename, textPositions [0], textPositions [1]);

                    m_codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation(m_debugger, m_locationAddress.ToString());

                    if (m_codeContext == null)
                    {
                        throw new InvalidOperationException();
                    }
                }
                else
                {
                    m_codeContext = CLangDebuggeeCodeContext.GetCodeContextForLocation(m_debugger, m_locationAddress.ToString());

                    m_documentContext = (m_codeContext != null) ? m_codeContext.DocumentContext : null;
                }
            }
            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);
            }
        }