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

    #endregion

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

    #region IDebugProgram3 Members

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

    public int ExecuteOnThread (IDebugThread2 pThread)
    {
      // 
      // Executes the debugger program. The thread is returned to give the debugger information on which thread the user is viewing when executing the program.
      // 

      LoggingUtils.PrintFunction ();

      try
      {
        uint threadId;

        CLangDebuggeeThread thread = pThread as CLangDebuggeeThread;

        LoggingUtils.RequireOk (thread.GetThreadId (out threadId));

        string command = "-thread-select " + threadId;

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

        MiResultRecord.RequireOk (resultRecord, command);

        CurrentThreadId = threadId;

        LoggingUtils.RequireOk (Execute ());

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

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

        public MiVariable CreateVariableFromExpression(CLangDebuggeeStackFrame stackFrame, string expression)
        {
            LoggingUtils.PrintFunction();

            try
            {
                LoggingUtils.RequireOk(stackFrame.GetThread(out IDebugThread2 stackThread));

                LoggingUtils.RequireOk(stackThread.GetThreadId(out uint stackThreadId));

                string command = string.Format("-var-create --thread {0} --frame {1} - * \"{2}\"", stackThreadId, stackFrame.StackLevel, expression);

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

                MiResultRecord.RequireOk(resultRecord, command);

                return(new MiVariable(expression, resultRecord.Results));
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);

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

        public override int SetValueAsString(string value, uint radix, uint timeout)
        {
            //
            // Sets the value of a property from a string.
            //

            LoggingUtils.PrintFunction();

            try
            {
                string command = string.Format("-var-assign \"{0}\" \"{1}\"", m_gdbVariable.Name, value);

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

                MiResultRecord.RequireOk(resultRecord, command);

                if (resultRecord.HasField("value"))
                {
                    m_gdbVariable.Populate(resultRecord.Results);

                    m_debugger.VariableManager.UpdateVariable(m_gdbVariable);

                    return(Constants.S_OK);
                }

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

                return(Constants.E_FAIL);
            }
        }
Beispiel #4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int ReadAt(IDebugMemoryContext2 pStartContext, uint dwCount, byte [] rgbMemory, out uint pdwRead, ref uint pdwUnreadable)
        {
            //
            // Reads a sequence of bytes, starting at a given location.
            //

            LoggingUtils.PrintFunction();

            try
            {
                CONTEXT_INFO [] contextInfoArray = new CONTEXT_INFO [1];

                LoggingUtils.RequireOk(pStartContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfoArray));

                string command = string.Format("-data-read-memory-bytes {0} {1}", contextInfoArray [0].bstrAddressAbsolute, dwCount);

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

                MiResultRecord.RequireOk(resultRecord, command);

                MiResultValueList memoryStreamList = (MiResultValueList)resultRecord ["memory"] [0];

                for (int s = 0; s < memoryStreamList.Values.Count; ++s)
                {
                    if (!memoryStreamList [s].HasField("contents"))
                    {
                        throw new InvalidOperationException("-data-read-memory-bytes result missing 'contents' field");
                    }

                    string hexValue = memoryStreamList [s] ["contents"] [0].GetString();

                    if ((hexValue.Length / 2) != dwCount)
                    {
                        throw new InvalidOperationException();
                    }

                    for (int i = 0; i < dwCount; ++i)
                    {
                        rgbMemory [i] = byte.Parse(hexValue.Substring(i * 2, 2), NumberStyles.HexNumber);
                    }
                }

                pdwRead = dwCount;

                pdwUnreadable = 0;

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

                pdwRead = 0;

                pdwUnreadable = dwCount;

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

        public void RefreshThread(uint tid)
        {
            LoggingUtils.PrintFunction();

            try
            {
                m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    string command = string.Format("-thread-info {0}", (tid == 0) ? "" : tid.ToString());

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

                    MiResultRecord.RequireOk(resultRecord, command);

                    if (!resultRecord.HasField("threads"))
                    {
                        throw new InvalidOperationException("-thread-info result missing 'threads' field");
                    }

                    MiResultValueList threadsValueList = (MiResultValueList)resultRecord ["threads"] [0];

                    List <MiResultValue> threadsData = threadsValueList.List;

                    bool refreshedProcesses = false;

                    for (int i = threadsData.Count - 1; i >= 0; --i) // reported threads are in descending order.
                    {
                        uint id = threadsData [i] ["id"] [0].GetUnsignedInt();

                        CLangDebuggeeThread thread = GetThread(id) ?? AddThread(id);

                        if (thread.RequiresRefresh)
                        {
                            MiResultValue threadData = threadsData [i];

                            if (!refreshedProcesses)
                            {
                                AndroidDevice hostDevice = DebugProgram.DebugProcess.NativeProcess.HostDevice;

                                hostDevice.RefreshProcesses(DebugProgram.DebugProcess.NativeProcess.Pid);

                                refreshedProcesses = true;
                            }

                            thread.Refresh(ref threadData);
                        }
                    }

                    if (resultRecord.HasField("current-thread-id"))
                    {
                        CurrentThreadId = resultRecord ["current-thread-id"] [0].GetUnsignedInt();
                    }
                });
            }
            catch (Exception e)
            {
                LoggingUtils.HandleException(e);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void DeleteGdbVariable(MiVariable gdbVariable)
        {
            LoggingUtils.PrintFunction();

            string command = string.Format("-var-delete \"{0}\"", gdbVariable.Name);

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

            MiResultRecord.RequireOk(resultRecord, command);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public void UpdateVariable(MiVariable variable)
        {
            LoggingUtils.PrintFunction();

            string command = string.Format("-var-update --all-values \"{0}\"", variable.Name);

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

            MiResultRecord.RequireOk(resultRecord, command);

            if (resultRecord.HasField("changelist"))
            {
                variable.Populate(resultRecord ["changelist"]);
            }
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int SetNextStatement(IDebugStackFrame2 stackFrame, IDebugCodeContext2 codeContext)
        {
            //
            // Sets the next statement to the given stack frame and code context.
            //

            LoggingUtils.PrintFunction();

            try
            {
                CONTEXT_INFO [] contextInfo = new CONTEXT_INFO [1];

                LoggingUtils.RequireOk(codeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfo));

                string location = "*" + contextInfo [0].bstrAddressAbsolute;

                m_debugProgram.AttachedEngine.NativeDebugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    //
                    // Create a temporary breakpoint to stop -exec-jump continuing when we'd rather it didn't.
                    //

                    string command = string.Format("-break-insert -t \"{0}\"", location);

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

                    MiResultRecord.RequireOk(resultRecord, command);

                    //
                    // Jump to the specified address location.
                    //

                    command = string.Format("-exec-jump --thread {0} \"{1}\"", m_threadId, location);

                    resultRecord = debugger.GdbClient.SendSyncCommand(command);

                    MiResultRecord.RequireOk(resultRecord, command);
                });

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

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

        public override int GetSize(out uint size)
        {
            //
            // Returns the size, in bytes, of the property value.
            //

            LoggingUtils.PrintFunction();

            size = 0;

            try
            {
                IDebugThread2 stackThread;

                uint stackThreadId;

                LoggingUtils.RequireOk(m_stackFrame.GetThread(out stackThread));

                LoggingUtils.RequireOk(stackThread.GetThreadId(out stackThreadId));

                string command = string.Format("-data-evaluate-expression --thread {0} --frame {1} --language c \"sizeof({2})\"", stackThreadId, (m_stackFrame as CLangDebuggeeStackFrame).StackLevel, m_expression);

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

                MiResultRecord.RequireOk(resultRecord, command);

                if (resultRecord.HasField("value"))
                {
                    size = resultRecord ["value"] [0].GetUnsignedInt();

                    return(Constants.S_GETSIZE_NO_SIZE);
                }

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

                return(Constants.E_FAIL);
            }
        }
Beispiel #10
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        #region IDebugBoundBreakpoint2 Members

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

        public override int Delete()
        {
            //
            // Deletes the breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                int handle = base.Delete();

                if (handle == Constants.E_BP_DELETED)
                {
                    return(handle);
                }

                LoggingUtils.RequireOk(handle);

                m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    string command = "-break-delete " + GdbBreakpoint.ID;

                    debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        MiResultRecord.RequireOk(resultRecord, command);
                    });
                });

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

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

        public int WriteAt(IDebugMemoryContext2 pStartContext, uint dwCount, byte [] rgbMemory)
        {
            //
            // Writes the specified number of bytes of memory, starting at the specified address.
            //

            LoggingUtils.PrintFunction();

            try
            {
                CONTEXT_INFO [] contextInfoArray = new CONTEXT_INFO [1];

                LoggingUtils.RequireOk(pStartContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE, contextInfoArray));

                StringBuilder stringBuilder = new StringBuilder((int)dwCount * 2);

                for (uint i = 0; i < dwCount; ++i)
                {
                    stringBuilder.Append(rgbMemory [i].ToString("x"));
                }

                string command = string.Format("-data-write-memory-bytes {0} {1} {2}", contextInfoArray [0].bstrAddressAbsolute, stringBuilder.ToString(), dwCount);

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

                MiResultRecord.RequireOk(resultRecord, command);

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

                return(Constants.E_FAIL);
            }
        }
Beispiel #12
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int Read(uint dwInstructions, enum_DISASSEMBLY_STREAM_FIELDS dwFields, out uint pdwInstructionsRead, DisassemblyData [] prgDisassembly)
        {
            //
            // Reads instructions starting from the current position in the disassembly stream.
            //

            LoggingUtils.PrintFunction();

            try
            {
                ulong startAddress = m_codeContext.Address.MemoryAddress;

                ulong endAddress = startAddress + ((ulong)(dwInstructions) * 4); // TODO: 4 for a 32-bit instruction set?

                string disassemblyCommand = string.Format("-data-disassemble -s 0x{0:X8} -e 0x{1:X8} -- 1", startAddress, endAddress);

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

                MiResultRecord.RequireOk(resultRecord, disassemblyCommand);

                if (!resultRecord.HasField("asm_insns"))
                {
                    throw new InvalidOperationException("-data-disassemble result missing 'asm_insns' field");
                }

                MiResultValueList assemblyRecords = (MiResultValueList)resultRecord ["asm_insns"] [0];

                long maxInstructions = Math.Min(assemblyRecords.Values.Count, dwInstructions);

                if (maxInstructions == 0)
                {
                    throw new InvalidOperationException();
                }

                int currentInstruction = 0;

                for (int i = 0; i < assemblyRecords.Values.Count; ++i)
                {
                    MiResultValue recordValue = assemblyRecords [i];

                    if (recordValue.Variable.Equals("src_and_asm_line"))
                    {
                        //
                        // Parse mixed-mode disassembly reports.
                        //

                        uint line = recordValue ["line"] [0].GetUnsignedInt();

                        string file = recordValue ["file"] [0].GetString();

                        MiResultValueList lineAsmInstructionValues = (MiResultValueList)recordValue ["line_asm_insn"] [0];

                        foreach (MiResultValue instructionValue in lineAsmInstructionValues.Values)
                        {
                            string address = instructionValue ["address"] [0].GetString();

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS) != 0)
                            {
                                prgDisassembly [currentInstruction].bstrAddress = address;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESS;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESSOFFSET) != 0)
                            {
                                string offset = instructionValue ["offset"] [0].GetString();

                                prgDisassembly [currentInstruction].bstrAddressOffset = offset;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_ADDRESSOFFSET;
                            }

                            if (((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE) != 0) || ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS) != 0) || ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS) != 0))
                            {
                                string inst = instructionValue ["inst"] [0].GetString();

                                string [] operations = inst.Split(new string [] { "\\t" }, StringSplitOptions.None);

                                if (operations.Length > 0)
                                {
                                    prgDisassembly [currentInstruction].bstrOpcode = operations [0];

                                    prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPCODE;
                                }

                                if (operations.Length > 1)
                                {
                                    prgDisassembly [currentInstruction].bstrOperands = operations [1];

                                    prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS;
                                }

                                if (operations.Length > 2)
                                {
                                    prgDisassembly [currentInstruction].bstrOperands += " " + operations [2];

                                    prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_OPERANDS_SYMBOLS;
                                }
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL) != 0)
                            {
                                string functionName = instructionValue ["func-name"] [0].GetString();

                                prgDisassembly [currentInstruction].bstrSymbol = functionName;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_SYMBOL;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID) != 0)
                            {
                                DebuggeeAddress instructionAddress = new DebuggeeAddress(address);

                                prgDisassembly [currentInstruction].uCodeLocationId = instructionAddress.MemoryAddress;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_CODELOCATIONID;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION) != 0)
                            {
                                prgDisassembly [currentInstruction].posBeg.dwLine = line;

                                prgDisassembly [currentInstruction].posBeg.dwColumn = 0;

                                prgDisassembly [currentInstruction].posEnd.dwLine = line;

                                prgDisassembly [currentInstruction].posEnd.dwColumn = uint.MaxValue;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_POSITION;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL) != 0)
                            {
                                prgDisassembly [currentInstruction].bstrDocumentUrl = "file://" + file;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_DOCUMENTURL;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET) != 0)
                            {
                                uint offset = instructionValue ["offset"] [0].GetUnsignedInt();

                                prgDisassembly [currentInstruction].dwByteOffset = offset;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_BYTEOFFSET;
                            }

                            if ((dwFields & enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS) != 0)
                            {
                                prgDisassembly [currentInstruction].dwFlags |= enum_DISASSEMBLY_FLAGS.DF_HASSOURCE;

                                prgDisassembly [currentInstruction].dwFields |= enum_DISASSEMBLY_STREAM_FIELDS.DSF_FLAGS;
                            }

                            if (++currentInstruction >= maxInstructions)
                            {
                                break;
                            }
                        }
                    }
                }

                pdwInstructionsRead = (uint)currentInstruction;

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

                pdwInstructionsRead = 0;

                return(Constants.E_FAIL);
            }
        }
Beispiel #13
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int SetCondition(BP_CONDITION bpCondition)
        {
            //
            // Sets or changes the condition associated with this bound breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                int handle = base.SetCondition(bpCondition);

                if (handle == Constants.E_BP_DELETED)
                {
                    return(handle);
                }

                LoggingUtils.RequireOk(handle);

                string condition = string.Empty;

                switch (bpCondition.styleCondition)
                {
                case enum_BP_COND_STYLE.BP_COND_WHEN_TRUE:
                {
                    condition = bpCondition.bstrCondition;

                    break;
                }

                case enum_BP_COND_STYLE.BP_COND_WHEN_CHANGED:
                {
                    throw new NotImplementedException();
                }
                }

                if (!string.IsNullOrEmpty(condition))
                {
                    m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                    {
                        string command = string.Format("-break-condition {0} \"{1}\"", GdbBreakpoint.ID, condition);

                        debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                        {
                            MiResultRecord.RequireOk(resultRecord, command);
                        });
                    });
                }

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

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

                return(Constants.E_FAIL);
            }
        }
Beispiel #14
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override int SetPassCount(BP_PASSCOUNT bpPassCount)
        {
            //
            // Sets or change the pass count associated with this bound breakpoint.
            //

            LoggingUtils.PrintFunction();

            try
            {
                int handle = base.SetPassCount(bpPassCount);

                if (handle == Constants.E_BP_DELETED)
                {
                    return(handle);
                }

                LoggingUtils.RequireOk(handle);

                uint passCount = 0;

                switch (bpPassCount.stylePassCount)
                {
                case enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_EQUAL:
                {
                    goto case enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_EQUAL_OR_GREATER;
                }

                case enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_EQUAL_OR_GREATER:
                {
                    passCount = bpPassCount.dwPassCount - 1;

                    break;
                }

                case enum_BP_PASSCOUNT_STYLE.BP_PASSCOUNT_MOD:
                {
                    throw new NotImplementedException();
                }
                }

                m_debugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                {
                    string command = string.Format("-break-after {0} {1}", GdbBreakpoint.ID, passCount);

                    debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        MiResultRecord.RequireOk(resultRecord, command);
                    });
                });

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

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

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

        private MiVariable [] GetChildVariables(MiVariable parentVariable, int depth)
        {
            LoggingUtils.PrintFunction();

            List <MiVariable> childVariables = new List <MiVariable> ();

            if ((depth > 0) && (parentVariable.HasChildren))
            {
                string command = string.Format("-var-list-children --all-values \"{0}\"", parentVariable.Name);

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

                MiResultRecord.RequireOk(resultRecord, command);

                if (resultRecord.HasField("children"))
                {
                    List <MiResultValue> childrenList = resultRecord ["children"] [0] ["child"];

                    for (int i = 0; i < childrenList.Count; ++i)
                    {
                        MiResultValueTuple childTuple = childrenList [i] as MiResultValueTuple;

                        string variableName = childTuple ["name"] [0].GetString();

                        MiVariable childVariable = null;

                        bool isPseudoChild = false;

                        if (childTuple.HasField("exp"))
                        {
                            string variableExpression = childTuple ["exp"] [0].GetString();

                            if (!string.IsNullOrEmpty(variableExpression))
                            {
                                childVariable = new MiVariable(variableName, variableExpression);

                                childVariable.Populate(childTuple.Values);

                                isPseudoChild = childVariable.IsPseudoChild;
                            }
                        }

                        if (childVariable == null)
                        {
                            childVariable = new MiVariable(variableName, childTuple.Values);
                        }

                        if (isPseudoChild)
                        {
                            depth += 1; // need an additional level of children.

                            MiVariable [] evaluatedChildren = GetChildVariables(childVariable, depth - 1);

                            foreach (MiVariable child in evaluatedChildren)
                            {
                                childVariable.AddChild(child);
                            }
                        }

                        childVariables.Add(childVariable);
                    }
                }
            }

            return(childVariables.ToArray());
        }
Beispiel #16
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        protected override int QueryRegisters()
        {
            LoggingUtils.PrintFunction();

            try
            {
                //
                // Returns a list of registers for the current stack level.
                //

                if (!m_queriedRegisters)
                {
                    uint threadId;

                    LoggingUtils.RequireOk(m_thread.GetThreadId(out threadId));

                    string command = string.Format("-data-list-register-values --thread {0} --frame {1} r", threadId, StackLevel);

                    m_debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        MiResultRecord.RequireOk(resultRecord, command);

                        if (!resultRecord.HasField("register-values"))
                        {
                            throw new InvalidOperationException("Failed to retrieve list of register values");
                        }

                        MiResultValue registerValues = resultRecord ["register-values"] [0];

                        int registerValuesCount = registerValues.Values.Count;

                        Dictionary <uint, string> registerIdMapping = m_debugger.GdbClient.GetRegisterIdMapping();

                        for (int i = 0; i < registerValuesCount; ++i)
                        {
                            uint registerId = registerValues [i] ["number"] [0].GetUnsignedInt();

                            string registerValue = registerValues [i] ["value"] [0].GetString();

                            string registerName = registerIdMapping [registerId];

                            string registerNamePrettified = "$" + registerName;

                            CLangDebuggeeProperty property = new CLangDebuggeeProperty(m_debugger, this, registerNamePrettified, registerValue);

                            m_stackRegisters.TryAdd(registerNamePrettified, property);

                            LoggingUtils.RequireOk(m_property.AddChildren(new DebuggeeProperty [] { property }));
                        }

                        m_queriedRegisters = true;
                    });
                }

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

                return(Constants.E_FAIL);
            }
        }
Beispiel #17
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        protected override int QueryArgumentsAndLocals()
        {
            LoggingUtils.PrintFunction();

            try
            {
                if (!m_queriedArgumentsAndLocals)
                {
                    uint threadId;

                    LoggingUtils.RequireOk(m_thread.GetThreadId(out threadId));

                    string command = string.Format("-stack-list-variables --thread {0} --frame {1} --no-values", threadId, StackLevel);

                    m_debugger.GdbClient.SendCommand(command, delegate(MiResultRecord resultRecord)
                    {
                        MiResultRecord.RequireOk(resultRecord, command);

                        if (resultRecord.HasField("variables"))
                        {
                            MiResultValue localVariables = resultRecord ["variables"] [0];

                            for (int i = 0; i < localVariables.Values.Count; ++i)
                            {
                                string variableName = localVariables [i] ["name"] [0].GetString();

                                MiVariable variable = m_debugger.VariableManager.CreateVariableFromExpression(this, variableName);

                                if (variable == null)
                                {
                                    continue;
                                }

                                CLangDebuggeeProperty property = m_debugger.VariableManager.CreatePropertyFromVariable(this, variable);

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

                                if (localVariables [i].HasField("arg"))
                                {
                                    m_stackArguments.TryAdd(variableName, property);

                                    LoggingUtils.RequireOk(m_property.AddChildren(new DebuggeeProperty [] { property }));
                                }
                                else
                                {
                                    m_stackLocals.TryAdd(variableName, property);

                                    LoggingUtils.RequireOk(m_property.AddChildren(new DebuggeeProperty [] { property }));
                                }

                                //LoggingUtils.RequireOk (m_property.AddChildren (new DebuggeeProperty [] { property }));
                            }

                            m_queriedArgumentsAndLocals = true;
                        }
                    });
                }

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

                return(Constants.E_FAIL);
            }
        }
Beispiel #18
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);
            }
        }
Beispiel #19
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);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public override List <DebuggeeStackFrame> StackTrace(uint depth)
        {
            //
            // Each thread maintains an internal cache of the last reported stack-trace. This is only cleared when threads are resumed via 'SetRunning(true)'.
            //

            LoggingUtils.PrintFunction();

            try
            {
                if (m_threadStackFrames.Count < depth)
                {
                    LoggingUtils.RequireOk(GetThreadId(out uint threadId));

                    m_debugProgram.AttachedEngine.NativeDebugger.RunInterruptOperation(delegate(CLangDebugger debugger)
                    {
                        //
                        // Determine the maximum available stack depth.
                        //

                        string command;

                        MiResultRecord resultRecord;

                        if (depth == uint.MaxValue)
                        {
                            command = string.Format("-stack-info-depth --thread {0}", threadId);

                            resultRecord = debugger.GdbClient.SendSyncCommand(command);

                            MiResultRecord.RequireOk(resultRecord, command);

                            depth = resultRecord ["depth"] [0].GetUnsignedInt();
                        }

                        //
                        // Acquire stack frame information for any levels which we're missing.
                        //

                        if (m_threadStackFrames.Count < depth)
                        {
                            command = string.Format("-stack-list-frames --thread {0} {1} {2}", threadId, m_threadStackFrames.Count, depth - 1);

                            resultRecord = debugger.GdbClient.SendSyncCommand(command);

                            MiResultRecord.RequireOk(resultRecord, command);

                            if (resultRecord.HasField("stack"))
                            {
                                MiResultValueList stackRecord = resultRecord ["stack"] [0] as MiResultValueList;

                                for (int i = 0; i < stackRecord.Values.Count; ++i)
                                {
                                    MiResultValueTuple frameTuple = stackRecord [i] as MiResultValueTuple;

                                    uint stackLevel = frameTuple ["level"] [0].GetUnsignedInt();

                                    string stackFrameId = m_threadName + "#" + stackLevel;

                                    CLangDebuggeeStackFrame stackFrame = new CLangDebuggeeStackFrame(debugger, this, frameTuple, stackFrameId);

                                    lock (m_threadStackFrames)
                                    {
                                        m_threadStackFrames.Add(stackFrame);
                                    }
                                }
                            }
                        }
                    });
                }

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

                throw;
            }
        }