Exemple #1
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeBreakpointBound(DebugBreakpointManager breakpointManager, DebuggeeBreakpointPending pendingBreakpoint, DebuggeeCodeContext codeContext)
        {
            if (breakpointManager == null)
            {
                throw new ArgumentNullException("breakpointManager");
            }

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

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

            m_breakpointManager = breakpointManager;

            m_pendingBreakpoint = pendingBreakpoint;

            m_codeContext = codeContext;

            m_breakpointResolution = new DebuggeeBreakpointResolution(m_codeContext, "<bound breakpoint>");

            m_breakpointEnabled = true;

            m_breakpointDeleted = false;

            m_hitCount = 0;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Subtract(ulong count, out IDebugMemoryContext2 offsetAddressContext)
        {
            //
            // Subtracts a specified value to the current context's address to create a new context.
            //

            LoggingUtils.PrintFunction();

            try
            {
                DebuggeeAddress offsetAddress = m_address.Subtract(count);

                offsetAddressContext = new DebuggeeCodeContext(m_engine, DocumentContext, offsetAddress);

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

                offsetAddressContext = null;

                return(Constants.E_FAIL);
            }
        }
Exemple #3
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeBreakpointError(DebugBreakpointManager breakpointManager, DebuggeeBreakpointPending pendingBreakpoint, DebuggeeCodeContext codeContext, string error)
        {
            if (breakpointManager == null)
            {
                throw new ArgumentNullException("breakpointManager");
            }

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

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

            m_breakpointManager = breakpointManager;

            m_pendingBreakpoint = pendingBreakpoint;

            m_codeContext = codeContext;

            m_breakpointResolution = new DebuggeeBreakpointResolution(m_codeContext, error);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int SetCodeContext(DebuggeeCodeContext codeContext)
        {
            LoggingUtils.PrintFunction();

            m_codeContext = codeContext;

            return(Constants.S_OK);
        }
Exemple #5
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public CLangDebuggeeDisassemblyStream(CLangDebugger debugger, enum_DISASSEMBLY_STREAM_SCOPE streamScope, IDebugCodeContext2 codeContext)
        {
            m_debugger = debugger;

            m_streamScope = streamScope;

            m_codeContext = codeContext as DebuggeeCodeContext;
        }
Exemple #6
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeBreakpointError(DebugBreakpointManager breakpointManager, DebuggeeBreakpointPending pendingBreakpoint, DebuggeeCodeContext codeContext, string error)
        {
            m_breakpointManager = breakpointManager ?? throw new ArgumentNullException(nameof(breakpointManager));

            m_pendingBreakpoint = pendingBreakpoint ?? throw new ArgumentNullException(nameof(pendingBreakpoint));

            m_codeContext = codeContext ?? throw new ArgumentNullException(nameof(codeContext));

            m_breakpointResolution = new DebuggeeBreakpointResolution(m_codeContext, error);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeBreakpointResolution(DebuggeeCodeContext codeContext, string message)
        {
            if (codeContext == null)
            {
                throw new ArgumentNullException("codeContext");
            }

            m_codeContext = codeContext;

            m_resolutionMessage = message;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeDocumentContext(DebugEngine engine, string fileName, TEXT_POSITION beginPosition, TEXT_POSITION endPosition)
        {
            m_engine = engine;

            m_fileName = PathUtils.ConvertPathCygwinToWindows(fileName);

            m_beginPosition = beginPosition;

            m_endPosition = endPosition;

            m_codeContext = null;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeBreakpointBound(DebugBreakpointManager breakpointManager, DebuggeeBreakpointPending pendingBreakpoint, DebuggeeCodeContext codeContext)
        {
            m_breakpointManager = breakpointManager ?? throw new ArgumentNullException(nameof(breakpointManager));

            m_pendingBreakpoint = pendingBreakpoint ?? throw new ArgumentNullException(nameof(pendingBreakpoint));

            m_codeContext = codeContext ?? throw new ArgumentNullException(nameof(codeContext));

            m_breakpointResolution = new DebuggeeBreakpointResolution(m_codeContext, "<bound breakpoint>");

            m_breakpointEnabled = true;

            m_breakpointDeleted = false;

            m_hitCount = 0;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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

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

                DebuggeeCodeContext codeContext = m_debugger.GetCodeContextForLocation(location);

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

                DebuggeeCodeContext [] codeContexts = new DebuggeeCodeContext [] { 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> ();
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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

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

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

        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);
            }
        }
Exemple #17
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public DebuggeeBreakpointResolution(DebuggeeCodeContext codeContext, string message)
        {
            m_codeContext = codeContext ?? throw new ArgumentNullException(nameof(codeContext));

            m_resolutionMessage = message ?? throw new ArgumentNullException(nameof(message));
        }
Exemple #18
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Seek(enum_SEEK_START dwSeekStart, IDebugCodeContext2 pCodeContext, ulong uCodeLocationId, long iInstructions)
        {
            //
            // Moves the read pointer in the disassembly stream a given number of instructions relative to a specified position.
            //

            LoggingUtils.PrintFunction();

            try
            {
                switch (dwSeekStart)
                {
                case enum_SEEK_START.SEEK_START_BEGIN:
                {
                    //
                    // Starts seeking at the beginning of the current document.
                    //

                    throw new NotImplementedException();
                }

                case enum_SEEK_START.SEEK_START_END:
                {
                    //
                    // Starts seeking at the end of the current document.
                    //

                    throw new NotImplementedException();
                }

                case enum_SEEK_START.SEEK_START_CURRENT:
                {
                    //
                    // Starts seeking at the current position of the current document.
                    //

                    ulong offsetAddress = m_codeContext.Address.MemoryAddress;

                    if (iInstructions > 0)
                    {
                        offsetAddress += (ulong)(iInstructions * 4);
                    }
                    else if (iInstructions < 0)
                    {
                        offsetAddress += (ulong)(Math.Abs(iInstructions) * 4);
                    }

                    m_codeContext.Address = new DebuggeeAddress(offsetAddress);

                    break;
                }

                case enum_SEEK_START.SEEK_START_CODECONTEXT:
                {
                    //
                    // Starts seeking at the given code context of the current document.
                    //

                    DebuggeeCodeContext codeContext = (pCodeContext as DebuggeeCodeContext);

                    ulong offsetAddress = codeContext.Address.MemoryAddress;

                    if (iInstructions > 0)
                    {
                        offsetAddress += (ulong)(iInstructions * 4);
                    }
                    else if (iInstructions < 0)
                    {
                        offsetAddress += (ulong)(Math.Abs(iInstructions) * 4);
                    }

                    m_codeContext.Address = new DebuggeeAddress(offsetAddress);

                    break;
                }

                case enum_SEEK_START.SEEK_START_CODELOCID:
                {
                    //
                    // Starts seeking at the given code location identifier.
                    //

                    ulong offsetAddress = uCodeLocationId;

                    if (iInstructions > 0)
                    {
                        offsetAddress += (ulong)(iInstructions * 4);
                    }
                    else if (iInstructions < 0)
                    {
                        offsetAddress += (ulong)(Math.Abs(iInstructions) * 4);
                    }

                    m_codeContext.Address = new DebuggeeAddress(offsetAddress);

                    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);
            }
        }
Exemple #19
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public CLangDebuggeeBreakpointError(CLangDebugger debugger, DebugBreakpointManager breakpointManager, DebuggeeBreakpointPending pendingBreakpoint, DebuggeeCodeContext codeContext, MiBreakpoint gdbBreakpoint, string error)
            : base(breakpointManager, pendingBreakpoint, codeContext, error)
        {
            m_debugger = debugger;

            GdbBreakpoint = gdbBreakpoint;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Compare(enum_CONTEXT_COMPARE contextCompare, IDebugMemoryContext2 [] compareToItems, uint compareToLength, out uint foundIndex)
        {
            //
            // Compares the memory context to each context in the given array in the manner indicated by compare flags,
            // returning an index of the first context that matches.
            //

            LoggingUtils.PrintFunction();

            try
            {
                if (compareToItems.Length != compareToLength)
                {
                    throw new ArgumentException("Comparing contexts of different sizes.");
                }

                //
                // Get the context info for the current object.
                //

                CONTEXT_INFO [] currentContextInfo = new CONTEXT_INFO [1];

                LoggingUtils.RequireOk(GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ALLFIELDS, currentContextInfo));

                for (uint i = 0; i < compareToLength; ++i)
                {
                    DebuggeeCodeContext compareTo = compareToItems [i] as DebuggeeCodeContext;

                    if (compareTo == null)
                    {
                        continue;
                    }

                    CONTEXT_INFO [] compareToInfo = new CONTEXT_INFO [1];

                    LoggingUtils.RequireOk(compareTo.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ALLFIELDS, compareToInfo));

                    if (!DebugEngine.ReferenceEquals(m_engine, compareTo.m_engine))
                    {
                        continue;
                    }

                    bool comparisonResult = false;

                    switch (contextCompare)
                    {
                    case enum_CONTEXT_COMPARE.CONTEXT_EQUAL:
                    {
                        comparisonResult = (currentContextInfo [0].bstrAddressAbsolute.CompareTo(compareToInfo [0].bstrAddressAbsolute) == 0);

                        break;
                    }

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN:
                    {
                        comparisonResult = (currentContextInfo [0].bstrAddressAbsolute.CompareTo(compareToInfo [0].bstrAddressAbsolute) < 0);

                        break;
                    }

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN:
                    {
                        comparisonResult = (currentContextInfo [0].bstrAddressAbsolute.CompareTo(compareToInfo [0].bstrAddressAbsolute) > 0);

                        break;
                    }

                    case enum_CONTEXT_COMPARE.CONTEXT_LESS_THAN_OR_EQUAL:
                    {
                        comparisonResult = (currentContextInfo [0].bstrAddressAbsolute.CompareTo(compareToInfo [0].bstrAddressAbsolute) <= 0);

                        break;
                    }

                    case enum_CONTEXT_COMPARE.CONTEXT_GREATER_THAN_OR_EQUAL:
                    {
                        comparisonResult = (currentContextInfo [0].bstrAddressAbsolute.CompareTo(compareToInfo [0].bstrAddressAbsolute) >= 0);

                        break;
                    }

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_PROCESS:
                    {
                        comparisonResult = true;

                        break;
                    }

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_FUNCTION:
                    {
                        comparisonResult = (currentContextInfo [0].bstrFunction.CompareTo(compareToInfo [0].bstrFunction) == 0);

                        break;
                    }

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_MODULE:
                    {
                        comparisonResult = (currentContextInfo [0].bstrModuleUrl.CompareTo(compareToInfo [0].bstrModuleUrl) == 0);

                        break;
                    }

                    case enum_CONTEXT_COMPARE.CONTEXT_SAME_SCOPE:
                    // Fallthrough.
                    default:
                    {
                        throw new NotImplementedException();
                    }
                    }

                    if (comparisonResult)
                    {
                        foundIndex = i;

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

                foundIndex = uint.MaxValue;

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

                foundIndex = uint.MaxValue;

                return(Constants.E_COMPARE_CANNOT_COMPARE);
            }

            foundIndex = uint.MaxValue;

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

        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);
            }
        }
Exemple #22
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public CLangDebuggeeBreakpointBound(CLangDebugger debugger, DebugBreakpointManager breakpointManager, DebuggeeBreakpointPending pendingBreakpoint, DebuggeeCodeContext codeContext, MiBreakpoint gdbBreakpoint)
            : base(breakpointManager, pendingBreakpoint, codeContext)
        {
            m_debugger = debugger;

            GdbBreakpoint = gdbBreakpoint;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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