예제 #1
0
        public int WriteAt(IDebugMemoryContext2 startMemoryContext, uint count, byte[] buffer)
        {
            CONTEXT_INFO[] contextInfos = new CONTEXT_INFO[1];
            startMemoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfos);
            ulong address;

            if (!DebugEngineUtil.GetAddressFromString(contextInfos[0].bstrAddress, out address))
            {
                Trace.WriteLine($"Failed to convert {contextInfos[0].bstrAddress} to address");
                return(VSConstants.E_FAIL);
            }
            SbError error;
            var     bytesWrote = _lldbProcess.WriteMemory(address, buffer, count, out error);

            if (error.Fail())
            {
                Trace.WriteLine($"Error: {error.GetCString()}");
                return(VSConstants.E_FAIL);
            }
            if (bytesWrote != count)
            {
                Trace.WriteLine(
                    $"Warning: only written {bytesWrote} out of {count} bytes to memory.");
                return(VSConstants.S_FALSE);
            }
            return(VSConstants.S_OK);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetName(out string contextName)
        {
            //
            // Gets the user-displayable name for this context
            //

            LoggingUtils.PrintFunction();

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

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

                contextName = contextInfoArray [0].bstrAddressAbsolute;

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

                contextName = string.Empty;

                return(Constants.E_FAIL);
            }
        }
예제 #3
0
        public int GetInfo(enum_CONTEXT_INFO_FIELDS fields, CONTEXT_INFO[] contextInfo)
        {
            var info = new CONTEXT_INFO();

            if ((enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS & fields) != 0)
            {
                // Field used for requesting data from Lldb.
                info.bstrAddress = _addressAsHexString;
                info.dwFields   |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
            }
            if ((enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE & fields) != 0)
            {
                // `Name` in the breakpoint list for Disassembly breakpoints and also
                // `Address` for all breakpoints types.
                info.bstrAddressAbsolute = _addressAsHexString;
                info.dwFields           |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
            }
            // Combination of cif_moduleUrl!cif_function is used in a `Function` column.
            // TODO: fix these values, currently they overwrite data from VS
            if ((enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL & fields) != 0)
            {
                info.bstrModuleUrl = "";
                info.dwFields     |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
            }

            if ((enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION & fields) != 0)
            {
                GetName(out string functionName);
                info.bstrFunction = functionName;
                info.dwFields    |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
            }
            // TODO: implement more info fields if we determine they are needed
            contextInfo[0] = info;
            return(VSConstants.S_OK);
        }
예제 #4
0
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public int GetCodeLocationId(IDebugCodeContext2 pCodeContext, out ulong puCodeLocationId)
        {
            //
            // Returns a code location identifier for a particular code context.
            //

            LoggingUtils.PrintFunction();

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

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

                if (contextInfoArray [0].bstrAddressAbsolute.StartsWith("0x"))
                {
                    puCodeLocationId = ulong.Parse(contextInfoArray [0].bstrAddressAbsolute.Substring(2), NumberStyles.HexNumber);
                }
                else
                {
                    puCodeLocationId = ulong.Parse(contextInfoArray [0].bstrAddressAbsolute, NumberStyles.HexNumber);
                }

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

                puCodeLocationId = 0ul;

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

    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;
      }
    }
예제 #6
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);
            }
        }
예제 #7
0
        public void GetInfoNone()
        {
            var contextInfo = new CONTEXT_INFO[1];

            Assert.AreEqual(VSConstants.S_OK,
                            memoryContext.GetInfo(0, contextInfo));
            Assert.AreEqual(0, (uint)contextInfo[0].dwFields);
        }
예제 #8
0
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            var info = new CONTEXT_INFO();

            info.dwFields = 0;
            pinfo[0]      = info;
            return(VSConstants.S_OK);
        }
예제 #9
0
        public static ulong GetAddress(this IDebugMemoryContext2 context)
        {
            var contextInfo = new CONTEXT_INFO[1];
            int res         = context.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo);

            Debug.Assert(res == VSConstants.S_OK);
            return(System.Convert.ToUInt64(contextInfo[0].bstrAddress, 16));
        }
예제 #10
0
        public void GetInfoName()
        {
            var contextInfo = new CONTEXT_INFO[1];

            Assert.AreEqual(VSConstants.S_OK,
                            memoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, contextInfo));
            Assert.AreEqual(enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, contextInfo[0].dwFields);
            Assert.AreEqual(TEST_NAME.Value, contextInfo[0].bstrFunction);
        }
예제 #11
0
        public void GetInfoAddress()
        {
            var contextInfo = new CONTEXT_INFO[1];

            Assert.AreEqual(VSConstants.S_OK,
                            memoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo));
            Assert.AreEqual(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo[0].dwFields);
            Assert.AreEqual(TEST_PC_STR, contextInfo[0].bstrAddress);
        }
예제 #12
0
        public async Task <IEnumerable <Core.SStackFrame> > GetCurrentCallStack(int requestedFrameCount)
        {
            await this.runner.WaitForBreakIn();

            List <Core.SStackFrame> results = new List <Core.SStackFrame>();

            IDebugThread2 thread = this.runner.CurrentThread;

            if (thread == null)
            {
                throw new DebuggerException("No thread was recorded.");
            }
            IEnumDebugFrameInfo2 frameEnumerator;

            thread.EnumFrameInfo((uint)(enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_STACKRANGE), 10, out frameEnumerator);

            using (new DisposableComReference(frameEnumerator)) {
                uint frameCount = 0;
                if (requestedFrameCount < 0)
                {
                    frameEnumerator.GetCount(out frameCount);
                }
                else
                {
                    frameCount = (uint)requestedFrameCount;
                }
                FRAMEINFO[] frames = new FRAMEINFO[frameCount];

                frameEnumerator.Reset();
                if (frameEnumerator.Next((uint)frames.Length, frames, ref frameCount) == S_OK)
                {
                    for (int i = 0; i < frameCount; ++i)
                    {
                        FRAMEINFO          frame = frames[i];
                        IDebugCodeContext2 codeContext;
                        if (frame.m_pFrame.GetCodeContext(out codeContext) == S_OK)
                        {
                            using (new DisposableComReference(codeContext)) {
                                CONTEXT_INFO[] contextInfo = new CONTEXT_INFO[1];
                                codeContext.GetInfo((uint)enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo);
                                ulong instructionAddress = ulong.Parse(contextInfo[0].bstrAddress.Substring(2), System.Globalization.NumberStyles.AllowHexSpecifier);
                                // TODO: the -8 below seems architecture dependent
                                results.Add(new SStackFrame()
                                {
                                    FrameAddress = frame.m_addrMin - 8, InstructionAddress = instructionAddress, StackAddress = frame.m_addrMax
                                });
                            }
                        }
                    }
                }

                return(results);
            }
        }
예제 #13
0
        public int CanSetNextStatement(IDebugStackFrame2 stackFrameOrigin,
                                       IDebugCodeContext2 codeContextDestination)
        {
            stackFrameOrigin.GetThread(out IDebugThread2 threadOrigin);
            if (threadOrigin == null)
            {
                return(VSConstants.E_FAIL);
            }

            threadOrigin.GetThreadId(out uint threadIdOrigin);
            if (threadIdOrigin != _id)
            {
                return(VSConstants.S_FALSE);
            }

            var contextInfosDestination = new CONTEXT_INFO[1];
            int result = codeContextDestination.GetInfo(
                enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS | enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION,
                contextInfosDestination);

            if (result != VSConstants.S_OK)
            {
                return(result);
            }

            string functionNameOrigin;

            if (!DebugEngineUtil.GetAddressFromString(contextInfosDestination[0].bstrAddress,
                                                      out ulong addressPc))
            {
                return(VSConstants.E_FAIL);
            }

            if (stackFrameOrigin is IDebugStackFrame stackFrameOriginCast)
            {
                stackFrameOriginCast.GetNameWithSignature(out functionNameOrigin);
            }
            else
            {
                stackFrameOrigin.GetName(out functionNameOrigin);
            }

            if (addressPc != _remoteThread.GetFrameAtIndex(0).GetPC() &&
                contextInfosDestination[0].bstrFunction != functionNameOrigin)
            {
                return(VSConstants.S_FALSE);
            }

            return(VSConstants.S_OK);
        }
예제 #14
0
        public int ReadAt(IDebugMemoryContext2 startMemoryContext, uint countToRead, byte[] memory,
                          out uint countRead, ref uint countUnreadable)
        {
            // |countUnreadable| can be null when calling from C++ according to Microsoft's doc.
            // However, countUnreadable == null will always return false in C# as an uint can never
            // be null. Accessing |countUnreadable| here might cause a NullReferenceException.
            // According to Microsoft's doc, |countUnreadable| is useful when there are
            // non -consecutive blocks of memory that are readable. For example, if we want to read
            // 100 bytes at a certain address and only the first 50 bytes and the last 20 bytes are
            // readable.  |countRead| would be 50 and |countUnreadable| should be 30. However,
            // LLDB's ReadMemory() doesn't provide this kind of output, so this is not
            // straightforward to implement.

            // TODO We should estimate |countUnreadable| from page boundaries.
            // Otherwise, the memory view might be missing some valid contents in the beginnings
            // of mapped regions.

            // Note: We need to make sure we never return S_OK while setting countRead and
            // countUnreadable to zero. That can send the memory view into an infinite loop
            // and freeze Visual Studio ((internal)).
            CONTEXT_INFO[] contextInfo = new CONTEXT_INFO[1];
            startMemoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo);
            ulong address;

            if (DebugEngineUtil.GetAddressFromString(contextInfo[0].bstrAddress, out address))
            {
                SbError error;
                try
                {
                    countRead = Convert.ToUInt32(_lldbProcess.ReadMemory(address, memory,
                                                                         countToRead, out error));
                    if (error.Fail() || countRead == 0)
                    {
                        countRead = 0;
                        return(VSConstants.E_FAIL);
                    }
                    return(VSConstants.S_OK);
                }
                catch (OverflowException e)
                {
                    Trace.WriteLine($"Warning: Failed to read memory.{Environment.NewLine}" +
                                    $"{e.ToString()}");
                    countRead = 0;
                    return(VSConstants.E_FAIL);
                }
            }
            countRead = 0;
            return(VSConstants.E_FAIL);
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        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);
            }
        }
예제 #16
0
        public static string GetMemoryReferenceFromIDebugProperty(IDebugProperty2 property)
        {
            if (property != null && property.GetMemoryContext(out IDebugMemoryContext2 memoryContext) == HRConstants.S_OK)
            {
                CONTEXT_INFO[] contextInfo = new CONTEXT_INFO[1];
                if (memoryContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, contextInfo) == HRConstants.S_OK)
                {
                    if (contextInfo[0].dwFields.HasFlag(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS))
                    {
                        return(contextInfo[0].bstrAddress);
                    }
                }
            }

            return(null);
        }
예제 #17
0
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            pinfo[0].dwFields = enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL | enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
            {
                pinfo[0].bstrModuleUrl = _fileName;
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
            }

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0)
            {
                pinfo[0].bstrAddress = _currentStatementRange.StartLine.ToString();
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
            }

            return VSConstants.S_OK;
        }
예제 #18
0
        public void CanSetNextStatementSameFunction()
        {
            const string NAME       = "test";
            var          threadId   = 1u;
            var          mockThread = Substitute.For <RemoteThread>();

            mockThread.GetThreadId().Returns(threadId);
            var    mockStackFrame = Substitute.For <IDebugStackFrame2>();
            string name;

            mockStackFrame.GetName(out name).Returns(x =>
            {
                x[0] = NAME;
                return(VSConstants.S_OK);
            });
            IDebugThread2 outThread;
            IDebugThread  thread = CreateDebugThread <IDebugThread>(mockThread);

            mockStackFrame.GetThread(out outThread).Returns(x =>
            {
                x[0] = thread;
                return(VSConstants.S_OK);
            });
            var mockCodeContext         = Substitute.For <IDebugCodeContext2>();
            var contextInfosDestination = Arg.Any <CONTEXT_INFO[]>();

            mockCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS |
                                    enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, contextInfosDestination).Returns(x =>
            {
                var infos = x[1] as CONTEXT_INFO[];
                infos[0]  = new CONTEXT_INFO
                {
                    bstrFunction = NAME,
                    bstrAddress  = "0xabcd",
                };
                return(VSConstants.S_OK);
            });
            Assert.AreEqual(VSConstants.S_OK, thread.CanSetNextStatement(mockStackFrame, mockCodeContext));
        }
예제 #19
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);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    public int GetCodeLocationId (IDebugCodeContext2 pCodeContext, out ulong puCodeLocationId)
    {
      // 
      // Returns a code location identifier for a particular code context.
      // 

      LoggingUtils.PrintFunction ();

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

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

        if (contextInfoArray [0].bstrAddressAbsolute.StartsWith ("0x"))
        {
          puCodeLocationId = ulong.Parse (contextInfoArray [0].bstrAddressAbsolute.Substring (2), NumberStyles.HexNumber);
        }
        else
        {
          puCodeLocationId = ulong.Parse (contextInfoArray [0].bstrAddressAbsolute, NumberStyles.HexNumber);
        }

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

        puCodeLocationId = 0ul;

        return Constants.E_FAIL;
      }
    }
예제 #21
0
        // Gets information that describes this context.
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {           
            try
            {
                pinfo[0].dwFields = 0;

                if (dwFields.HasFlag(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS))
                {
                    pinfo[0].bstrAddress = m_address.ToString();
                    pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
                }

                // Fields not supported by the sample
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0){}
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0){}
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0){}
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0) {}
                //if ((dwFields & (uint)enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0) {}

                return VSConstants.S_OK;
            }
            //catch (ComponentException e)
            //{
            //    return e.HResult;
            //}
            catch (Exception e)
            {
                return EngineUtils.UnexpectedException(e);
            }
        }
예제 #22
0
 public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
 {
     throw new NotImplementedException();
 }
        // Gets information that describes this context.
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo) {
            pinfo[0].dwFields = 0;

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0) {
                pinfo[0].bstrAddress = _line.ToString(CultureInfo.InvariantCulture);
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
            }

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0 && _frame != null) {
                pinfo[0].bstrFunction = _frame.FunctionName;
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
            }

            // Fields not supported by the sample
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0) {
            }
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0) {
            }
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0) {
            }
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0) {
            }

            return VSConstants.S_OK;
        }
예제 #24
0
        public static TextPositionTuple GetTextPositionOfFrame(PathConverter converter, IDebugStackFrame2 frame)
        {
            IDebugDocumentContext2 documentContext;
            var source = new Source();

            if (frame.GetDocumentContext(out documentContext) == 0 &&
                documentContext != null)
            {
                var beginPosition = new TEXT_POSITION[1];
                var endPosition   = new TEXT_POSITION[1];
                documentContext.GetStatementRange(beginPosition, endPosition);

                string filePath;
                documentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out filePath);

                string convertedFilePath = converter.ConvertDebuggerPathToClient(filePath);
                // save the filename as we need it in any case
                source.Name = Path.GetFileName(convertedFilePath);

                // we have debug info but do we actually have the source code?
                if (File.Exists(convertedFilePath))
                {
                    source.Path = convertedFilePath;
                    int srcline   = converter.ConvertDebuggerLineToClient((int)beginPosition[0].dwLine);
                    int srccolumn = unchecked ((int)(beginPosition[0].dwColumn + 1));

                    return(new TextPositionTuple(source, srcline, srccolumn));
                }
            }

            // this frame is lacking source code
            source.Name   = Path.ChangeExtension(source.Name, ".s") ?? "???";
            source.Path   = null;
            source.Origin = "disassembly";
            ulong startAddress;

            IDebugCodeContext2 codeContext;

            if (frame.GetCodeContext(out codeContext) != HRConstants.S_OK)
            {
                return(null); // we couldn't even find the current instruction, something's really wrong
            }
            var cinfos = new CONTEXT_INFO[1];

            codeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ALLFIELDS, cinfos);

            DisassembledRange disRange;

            startAddress = (ulong)Convert.ToInt64(cinfos[0].bstrAddress, 16);

            int  idx     = DisasmRangesDict.FindUpperBound(startAddress);
            bool foundIt = false;
            int  column  = 0;
            int  line    = 0;

            if (idx > 0)
            {
                var kv = DisasmRangesDict.TryGet(idx - 1).Value;
                if (startAddress >= kv.Key && startAddress <= kv.Value.endAddress)
                {
                    disRange = kv.Value;
                    source.SourceReference = disRange.sourceReference;
                    line = kv.Value.dasmData.FirstIndexWhere(d => (ulong)Convert.ToInt64(d.bstrAddress, 16) >= startAddress) ?? 0;
                    ++line;
                    column  = 0;
                    foundIt = true;
                }
            }

            if (!foundIt)
            {
                IDebugThread2 thread;
                frame.GetThread(out thread);
                IDebugProgram2 program;
                thread.GetProgram(out program);
                IDebugDisassemblyStream2 disasmStream;
                program.GetDisassemblyStream(enum_DISASSEMBLY_STREAM_SCOPE.DSS_FUNCTION, codeContext, out disasmStream);
                uint instructionsRead;
                var  dasmData = new DisassemblyData[100];
                if (disasmStream.Read(100, enum_DISASSEMBLY_STREAM_FIELDS.DSF_ALL, out instructionsRead, dasmData) == HRConstants.S_OK)
                {
                    System.Array.Resize(ref dasmData, (int)instructionsRead);
                    source.SourceReference = ++lastSourceReference;
                    DisasmRangesDict.Add(startAddress, new DisassembledRange()
                    {
                        sourceReference = lastSourceReference,
                        endAddress      = (ulong)Convert.ToInt64(dasmData.Last().bstrAddress, 16),
                        dasmData        = dasmData
                    });
                    line   = 1;
                    column = 0;
                }
            }

            return(new TextPositionTuple(source, line, column));
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    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;
      }
    }
예제 #26
0
        public void SetNextStatement()
        {
            // We need CanSetNextStatement() to pass in order to execute SetNexStatement().
            const string NAME       = "test";
            const ulong  ADDRESS    = 0xabcd;
            var          threadId   = 1u;
            var          mockThread = Substitute.For <RemoteThread>();

            mockThread.GetThreadId().Returns(threadId);
            var    mockStackFrame = Substitute.For <IDebugStackFrame2>();
            string name;

            mockStackFrame.GetName(out name).Returns(x =>
            {
                x[0] = NAME;
                return(VSConstants.S_OK);
            });
            IDebugThread2 outThread;
            IDebugThread  thread = CreateDebugThread <IDebugThread>(mockThread);

            mockStackFrame.GetThread(out outThread).Returns(x =>
            {
                x[0] = thread;
                return(VSConstants.S_OK);
            });
            var mockCodeContext         = Substitute.For <IDebugCodeContext2>();
            var contextInfosDestination = Arg.Any <CONTEXT_INFO[]>();

            mockCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS |
                                    enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, contextInfosDestination).Returns(x =>
            {
                var infos = x[1] as CONTEXT_INFO[];
                infos[0]  = new CONTEXT_INFO
                {
                    bstrFunction = NAME,
                    bstrAddress  = "0x" + ADDRESS.ToString("x16"),
                };
                return(VSConstants.S_OK);
            });
            IDebugDocumentContext2 documentContext;
            var mockDocumentContext = Substitute.For <IDebugDocumentContext2>();

            mockCodeContext.GetDocumentContext(out documentContext).Returns(x =>
            {
                x[0] = mockDocumentContext;
                return(VSConstants.S_OK);
            });
            const uint   LINE = 2;
            const string PATH = "path\\to\\file";
            string       path;

            mockDocumentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out path).Returns(x =>
            {
                x[1] = PATH;
                return(VSConstants.S_OK);
            });
            mockDocumentContext.GetStatementRange(
                Arg.Any <TEXT_POSITION[]>(), Arg.Any <TEXT_POSITION[]>()).Returns(x =>
            {
                var startPosition       = x[0] as TEXT_POSITION[];
                startPosition[0].dwLine = LINE;
                return(VSConstants.S_OK);
            });
            var mockError = Substitute.For <SbError>();

            mockError.Fail().Returns(false);
            mockThread.JumpToLine(PATH, LINE).Returns(mockError);
            Assert.AreEqual(VSConstants.S_OK,
                            thread.SetNextStatement(mockStackFrame, mockCodeContext));
            mockThread.Received(1).JumpToLine(PATH, LINE + 1);
        }
예제 #27
0
        // Gets information that describes this context.
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo) {
            pinfo[0].dwFields = 0;

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0) {
                pinfo[0].bstrAddress = _lineNo.ToString();
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
            }

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0 && _frame != null) {
                pinfo[0].bstrFunction = _frame.FunctionName;
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
            }

            return VSConstants.S_OK;
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    protected override int SetInfo (enum_CONTEXT_INFO_FIELDS requestedFields, CONTEXT_INFO [] infoArray)
    {
      LoggingUtils.PrintFunction ();

      try
      {
        LoggingUtils.RequireOk (base.SetInfo (requestedFields, infoArray));

        if ((requestedFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
        {
          infoArray [0].bstrModuleUrl = m_symbolModule;

          infoArray [0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
        }

        if ((requestedFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0)
        {
          infoArray [0].bstrFunction = m_symbolName;

          infoArray [0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
        }

        if ((requestedFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0)
        {
          infoArray [0].bstrAddressOffset = m_symbolOffset;

          infoArray [0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET;
        }

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

        return Constants.E_FAIL;
      }
    }
예제 #29
0
        int IDebugMemoryContext2.GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo) {
            pinfo[0].dwFields = 0;

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0) {
                pinfo[0].bstrAddress = LineNumber.ToString();
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
            }

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0) {
                pinfo[0].bstrFunction = StackFrame?.StackFrame?.CallingFrame?.Call ?? "<unknown>";
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
            }

            return VSConstants.S_OK;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        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);
        }
예제 #31
0
        // Gets information that describes this context.
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            pinfo[0].dwFields = 0;

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0) {
                pinfo[0].bstrAddress = _lineNo.ToString();
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
            }

            // Fields not supported by the sample
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0) { }
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0) { }
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0) { }
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0) { }
            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0) { }

            return VSConstants.S_OK;
        }
예제 #32
0
 public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
 {
     return VSConstants.E_FAIL;
 }
예제 #33
0
 /// <summary>
 /// Retrieves a CONTEXT_INFO structure that describes the context.
 /// </summary>
 /// <param name="dwFields"> A combination of flags from the CONTEXT_INFO_FIELDS enumeration that indicate which fields of the CONTEXT_INFO structure are to be fill in.</param>
 /// <param name="pinfo">The CONTEXT_INFO structure that is filled in.</param>
 /// <returns>If successful, returns S_OK; otherwise, returns an error code.</returns>
 public virtual int GetInfo( enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo )
 {
     Logger.Debug( string.Empty );
     return VSConstants.E_NOTIMPL;
 }
    int IDebugCodeContext2.GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
    {
      Debug.WriteLine("AD7DocumentContext: GetInfo");
      pinfo[0].dwFields = 0;

      if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0)
      {
        pinfo[0].bstrFunction = _rs.OwningRoutine.Name;
        pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
      }

      if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
      {
        pinfo[0].bstrModuleUrl = _fileName;
        pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
      }

      if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0)
      {
        pinfo[0].bstrAddress = LineNumber.ToString();
        pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
      }

      return VSConstants.S_OK;
    }
예제 #35
0
 int IDebugCodeContext2.GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo) {
     return IDebugMemoryContext2.GetInfo(dwFields, pinfo);
 }
예제 #36
0
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            var info = new CONTEXT_INFO();

            int ret = VSConstants.S_FALSE;
            info.dwFields = 0;

            var loc = DocumentContext == null ? null : DocumentContext.DocumentLocation;
            if (loc == null)
            {
                ret = VSConstants.E_FAIL;
            }
            else
            {
                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0)
                {
                    info.bstrFunction = loc.MethodName;
                    info.dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
                }

                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0)
                {
                    if (loc.SourceCode != null && !loc.SourceCode.IsSpecial)
                    {
                        info.dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET;
                        info.posFunctionOffset.dwLine = (uint) loc.SourceCode.Position.MethodOffset;
                    }
                }

                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0)
                {
                    info.bstrAddress = loc.Location.Index.ToString("X3").PadLeft(4);
                    info.dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
                }

                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
                {
                    info.bstrModuleUrl = "<default>";
                    info.dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
                }

                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0)
                {
                    info.bstrAddressAbsolute = loc.Location.ToString();
                    info.dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
                }
            }

            pinfo[0] = info;
            return ret;
        }
예제 #37
0
        private string InterpolateToken(string token, IDebugThread2 pThread, IDebugStackFrame2 topFrame, uint radix, string processName, int processId)
        {
            switch (token)
            {
            case "$FUNCTION":
            {
                int hr = topFrame.GetCodeContext(out IDebugCodeContext2 pCodeContext);
                if (hr >= 0)
                {
                    CONTEXT_INFO[] pInfo = new CONTEXT_INFO[1];
                    hr = pCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION, pInfo);
                    if (hr >= 0)
                    {
                        return(pInfo[0].bstrFunction);
                    }
                }
                return(string.Format(CultureInfo.InvariantCulture, "<No Function Found>"));
            }

            case "$ADDRESS":
            {
                int hr = topFrame.GetCodeContext(out IDebugCodeContext2 pCodeContext);
                if (hr >= 0)
                {
                    CONTEXT_INFO[] pInfo = new CONTEXT_INFO[1];
                    hr = pCodeContext.GetInfo(enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS, pInfo);
                    if (hr >= 0)
                    {
                        return(pInfo[0].bstrAddress);
                    }
                }
                return(string.Format(CultureInfo.InvariantCulture, "<No Address Found>"));
            }

            case "$FILEPOS":
            {
                int hr = topFrame.GetDocumentContext(out IDebugDocumentContext2 pDocumentContext);
                if (hr >= 0)
                {
                    hr = pDocumentContext.GetName(enum_GETNAME_TYPE.GN_FILENAME, out string fileName);
                    if (hr >= 0)
                    {
                        TEXT_POSITION[] textPosBeg = new TEXT_POSITION[1];
                        TEXT_POSITION[] textPosEnd = new TEXT_POSITION[1];
                        hr = pDocumentContext.GetStatementRange(textPosBeg, textPosEnd);
                        if (hr >= 0)
                        {
                            return(string.Format(CultureInfo.InvariantCulture, "{0}:{1}", fileName, textPosBeg[0].dwLine + 1));
                        }
                    }
                }
                return(string.Format(CultureInfo.InvariantCulture, "<No File Position>"));
            }

            case "$CALLER":
            {
                IEnumDebugFrameInfo2 frameInfoEnum;
                int hr = pThread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_FLAGS, Constants.EvaluationRadix, out frameInfoEnum);
                if (hr >= 0)
                {
                    FRAMEINFO[] frames  = new FRAMEINFO[2];
                    uint        fetched = 0;
                    hr = frameInfoEnum.Next(2, frames, ref fetched);
                    if (hr < 0 && fetched == 2)
                    {
                        return(frames[1].m_bstrFuncName);
                    }
                }
                return(string.Format(CultureInfo.InvariantCulture, "<No Caller Avaliable>"));
            }

            case "$TID":
            {
                int hr = pThread.GetThreadId(out uint threadId);
                if (hr == 0)
                {
                    if (radix == 16)
                    {
                        return(string.Format(CultureInfo.InvariantCulture, "{0:X}", threadId));
                    }
                    else
                    {
                        return(string.Format(CultureInfo.InvariantCulture, "{0}", threadId));
                    }
                }
                return(string.Format(CultureInfo.InvariantCulture, "<No Thread Id>"));
            }

            case "$TNAME":
            {
                int hr = pThread.GetName(out string name);
                if (hr == 0)
                {
                    return(name);
                }
                return(string.Format(CultureInfo.InvariantCulture, "<No Thread Name>"));
            }

            case "$PID":
            {
                if (processId != Constants.InvalidProcessId)
                {
                    return(processId.ToString(CultureInfo.InvariantCulture));
                }
                return(string.Format(CultureInfo.InvariantCulture, "<Unknown PID>", token));
            }

            case "$PNAME":
            {
                return(processName);
            }

            case "$CALLSTACK":
            {
                IEnumDebugFrameInfo2 frameInfoEnum;
                int           hr    = pThread.EnumFrameInfo(enum_FRAMEINFO_FLAGS.FIF_FRAME | enum_FRAMEINFO_FLAGS.FIF_FLAGS, Constants.EvaluationRadix, out frameInfoEnum);
                int           count = 0;
                StringBuilder sb    = new StringBuilder();
                while (count < Constants.DefaultTracepointCallstackDepth)
                {
                    FRAMEINFO[] frames  = new FRAMEINFO[1];
                    uint        fetched = 0;
                    hr = frameInfoEnum.Next(1, frames, ref fetched);
                    if (fetched == 1)
                    {
                        // TODO: Do we want function arguments?
                        frames[0].m_pFrame.GetName(out string name);
                        sb.AppendLine(name);
                    }
                    count++;
                }
                return(sb.ToString());
            }

            case "$TICK":
                return(string.Format(CultureInfo.InvariantCulture, "{0}", Environment.TickCount));

            default:
                return(string.Format(CultureInfo.InvariantCulture, "<Unknown Token: ${0}>", token));
            }
        }
 int IDebugMemoryContext2.GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
 {
   Debug.WriteLine("AD7DocumentContext: GetInfo");
   throw new NotImplementedException();
 }
예제 #39
0
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            if (pinfo == null)
                throw new ArgumentNullException("pinfo");
            if (pinfo.Length < 1)
                throw new ArgumentException();

            bool getModuleUrl = (dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0;
            bool getFunction = (dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0;
            bool getFunctionOffset = (dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0;
            bool getAddress = (dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0;
            bool getAddressOffset = (dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0;
            bool getAddressAbsolute = (dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0;

            if (getModuleUrl)
            {
                // The name of the module where the context is located
                //pinfo[0].bstrModuleUrl = "";
                //pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
            }

            if (getFunction)
            {
                // The function name where the context is located
                pinfo[0].bstrFunction = string.Format("{0}.{1}({2})", _location.GetDeclaringType().GetName(), _location.GetMethod().GetName(), string.Join(", ", _location.GetMethod().GetArgumentTypeNames()));
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
            }

            if (getFunctionOffset)
            {
                // A TEXT_POSITION structure that identifies the line and column offset of the function associated with the code context
                pinfo[0].posFunctionOffset.dwLine = (uint)_location.GetLineNumber();
                pinfo[0].posFunctionOffset.dwColumn = 0;
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET;
            }

            if (getAddress)
            {
                // The address in code where the given context is located
                //pinfo[0].bstrAddress = "";
                //pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
            }

            if (getAddressOffset)
            {
                // The offset of the address in code where the given context is located
                //pinfo[0].bstrAddressOffset = "";
                //pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET;
            }

            if (getAddressAbsolute)
            {
                // The absolute address in memory where the given context is located
                //pinfo[0].bstrAddressAbsolute = "";
                //pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
            }

            return VSConstants.S_OK;
        }
        //TODO
        public object RetrieveObject(string addressExpressionString)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            StackFrame2 currentFrame2 = this.m_Dte2.Debugger.CurrentStackFrame as StackFrame2;

            if (currentFrame2 == null)
            {
                return(null);
            }

            // Depth property is 1-based.
            uint currentFrameDepth = currentFrame2.Depth - 1;

            // Get frame info enum interface.
            IDebugThread2        currentThread2 = this.DebugThread;
            IEnumDebugFrameInfo2 enumDebugFrameInfo2;

            if (VSConstants.S_OK != currentThread2.EnumFrameInfo((uint)enum_FRAMEINFO_FLAGS.FIF_FRAME, 0, out enumDebugFrameInfo2))
            {
                return(null);
            }

            // Skip frames above the current one.
            enumDebugFrameInfo2.Reset();
            if (VSConstants.S_OK != enumDebugFrameInfo2.Skip(currentFrameDepth))
            {
                return(null);
            }

            // Get the current frame.
            FRAMEINFO[] frameInfo = new FRAMEINFO[1];
            uint        fetched   = 0;
            int         hr        = enumDebugFrameInfo2.Next(1, frameInfo, ref fetched);

            if (hr != VSConstants.S_OK || fetched != 1)
            {
                return(null);
            }

            IDebugStackFrame2 stackFrame = frameInfo[0].m_pFrame;

            if (stackFrame == null)
            {
                return(null);
            }

            // Get a context for evaluating expressions.
            IDebugExpressionContext2 expressionContext;

            if (VSConstants.S_OK != stackFrame.GetExpressionContext(out expressionContext))
            {
                return(null);
            }

            // Parse the expression string.
            IDebugExpression2 expression;
            string            error;
            uint errorCharIndex;

            if (VSConstants.S_OK != expressionContext.ParseText($"{addressExpressionString}.Ptr", (uint)enum_PARSEFLAGS.PARSE_EXPRESSION, 10, out expression, out error, out errorCharIndex))
            {
                return(null);
            }

            // Evaluate the parsed expression.
            IDebugProperty2 debugProperty = null;
            IDebugProperty3 upgrade       = debugProperty as IDebugProperty3;

            if (VSConstants.S_OK != expression.EvaluateSync((uint)enum_EVALFLAGS.EVAL_NOSIDEEFFECTS, unchecked ((uint)Timeout.Infinite), null, out debugProperty))
            {
                return(null);
            }

            DEBUG_PROPERTY_INFO[] test2 = new DEBUG_PROPERTY_INFO[64];
            debugProperty.GetPropertyInfo((uint)(enum_DEBUGPROP_INFO_FLAGS.DEBUGPROP_INFO_ALL), 10, unchecked ((uint)Timeout.Infinite), null, 0, test2);
            uint bmpSize = 0;
            var  re      = debugProperty.GetSize(out bmpSize);

            // Get memory context for the property.
            IDebugReference2 reference;

            debugProperty.GetReference(out reference);

            IDebugMemoryBytes2 bytes2;

            debugProperty.GetMemoryBytes(out bytes2);

            IDebugMemoryContext2 memoryContext;

            if (VSConstants.S_OK != debugProperty.GetMemoryContext(out memoryContext))
            {
                // In practice, this is where it seems to fail if you enter an invalid expression.
                return(null);
            }

            CONTEXT_INFO[] bfnl = new CONTEXT_INFO[64];
            memoryContext.GetInfo((uint)enum_CONTEXT_INFO_FIELDS.CIF_ALLFIELDS, bfnl);

            // Get memory bytes interface.
            IDebugMemoryBytes2 memoryBytes;

            if (VSConstants.S_OK != debugProperty.GetMemoryBytes(out memoryBytes))
            {
                return(null);
            }

            string memoryAddress;

            memoryContext.GetName(out memoryAddress);

            int intValue = Convert.ToInt32(memoryAddress, 16);

            var process = GetDebuggedProcess(this.m_Dte2.Debugger);
            var thread  = process.GetThreads().FirstOrDefault(t => t.SystemPart.Id == this.m_Dte2.Debugger.CurrentThread.ID);
            //var stackRange = thread.GetStackAddressRange();
            var            stack = thread.GetTopStackFrame();
            ICorDebugValue value = null;

            //var getproperty = stack.GetProperty(value, addressExpressionString);

            //byte[] processRam = new byte[1000000];
            //process.ReadMemory((ulong)intValue, DkmReadMemoryFlags.None, processRam);
            //string test23 = System.Text.Encoding.ASCII.GetString(processRam, 0, processRam.Length);

            //byte[] processRam2 = new byte[stack.FrameSize];
            //process.ReadMemory((ulong)stack.FrameBase, DkmReadMemoryFlags.None, processRam2);
            //string test13 = System.Text.Encoding.ASCII.GetString(processRam2, 0, processRam2.Length);

            try
            {
                Emgu.CV.Image <Gray, byte> img431 = new Emgu.CV.Image <Gray, byte>(800, 600, 800, new IntPtr(intValue));



                int      width           = 800;
                int      height          = 600;
                int      pixelFormatSize = Image.GetPixelFormatSize(System.Drawing.Imaging.PixelFormat.Format32bppArgb) / 8;
                int      stride          = width * pixelFormatSize;
                byte[]   bits            = new byte[stride * height];
                GCHandle handle          = GCHandle.Alloc(bits, GCHandleType.Pinned);
                IntPtr   pointer         = Marshal.UnsafeAddrOfPinnedArrayElement(bits, 0);
                Bitmap   bitmap          = new Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format32bppArgb, pointer);

                //Bitmap bmp = new Bitmap(800, 600);
                //IntPtr parameter = new IntPtr(intValue);
                //GCHandle handle = GCHandle.Alloc(bmp, GCHandleType.Normal);
                //Marshal.Copy(processRam, 0, pointer, processRam.Length);
                handle.Free();


                object o = handle.Target;
            }
            catch (Exception ex)
            {
            }
            //try
            //{
            //    IntPtr ptr = new IntPtr(intValue);
            //    GCHandle imageHandle = GCHandle.FromIntPtr(ptr);
            //    object obj = imageHandle.Target;
            //}
            //catch(Exception ex)
            //{

            //}

            // The number of bytes to read.
            ulong dataSize = 0;
            var   res      = memoryBytes.GetSize(out dataSize);

            unsafe
            {
                dataSize = 1024 * 1024;
            }
            //if (VSConstants.S_OK != res)
            //{
            //    return null;
            //}

            //// Allocate space for the result.
            byte[] data         = new byte[dataSize];
            uint   writtenBytes = 0;

            int size = 0;

            data = this.ReadMemory(memoryContext, memoryBytes, (int)dataSize, 1024, out size);
            Emgu.CV.Image <Gray, byte> img = new Emgu.CV.Image <Gray, byte>(800, 600);
            Marshal.Copy(data, 0, img.Ptr, size);

            // Read data from the debuggee.
            uint unreadable = 0;

            hr = memoryBytes.ReadAt(memoryContext, (uint)dataSize, data, out writtenBytes, ref unreadable);

            if (hr != VSConstants.S_OK)
            {
                // Read failed.

                Marshal.Copy(new IntPtr(intValue), data, 0, data.Length);
            }
            else //if (writtenBytes < dataSize)
            {
                // Read partially succeeded.

                try
                {
                    //Marshal.Copy(new IntPtr(intValue), data, 0, (int)writtenBytes);

                    BinaryFormatter ser = new BinaryFormatter();
                    using (MemoryStream stream = new MemoryStream(data, 0, (int)writtenBytes))
                    {
                        MemoryStream outStream = new MemoryStream();
                        ser.Serialize(outStream, new Bitmap(800, 600));
                        byte[] serializedImage = outStream.GetBuffer();
                        string test            = System.Text.Encoding.UTF8.GetString(serializedImage);
                        string test3           = System.Text.Encoding.ASCII.GetString(serializedImage);

                        //var img = Image.FromStream(stream);
                        object obj = ser.Deserialize(stream);
                    }
                }
                catch (Exception ex)
                {
                    string test  = System.Text.Encoding.UTF8.GetString(data, 0, (int)writtenBytes);
                    string test3 = System.Text.Encoding.ASCII.GetString(data, 0, (int)writtenBytes);
                }

                //IntPtr parameter = new IntPtr(intValue);
                //GCHandle handle = (GCHandle)parameter;

                //object o = handle.Target;
            }
            //else
            //{
            //    // Read successful.
            //}

            return(null);
        }
예제 #41
0
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            pinfo[0].dwFields = enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL | enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
            {
                pinfo[0].bstrModuleUrl = FileName;
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
            }

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0)
            {

                pinfo[0].bstrAddress = _textPosition.BeginPosition.dwLine.ToString();
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
            }

            return VSConstants.S_OK;
        }
예제 #42
0
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            pinfo[0].dwFields = 0;

            Log.Debug("ScriptDocumentContext: IDebugCodeCotnext2.GetInfo");

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0)
            {
                pinfo[0].bstrFunction = "TestFunc";
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;    
            }

            if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
            {
                pinfo[0].bstrModuleUrl = _fileName;
                pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
            }
            
            return VSConstants.S_OK;
        }
예제 #43
0
        // Gets information that describes this context.
        public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo)
        {
            try
            {
                pinfo[0].dwFields = 0;

                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS) != 0)
                {
                    pinfo[0].bstrAddress = EngineUtils.AsAddr(_address);
                    pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESS;
                }

                // Fields not supported by the sample
                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSOFFSET) != 0) { }
                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE) != 0)
                {
                    pinfo[0].bstrAddressAbsolute = EngineUtils.AsAddr(_address);
                    pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_ADDRESSABSOLUTE;
                }
                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL) != 0)
                {
                    DebuggedModule module = _engine.DebuggedProcess.ResolveAddress(_address);
                    if (module != null)
                    {
                        pinfo[0].bstrModuleUrl = module.Name;
                        pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_MODULEURL;
                    }
                }
                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION) != 0)
                {
                    if (_functionName == null)
                    {
                        _functionName = Engine.GetAddressDescription(_address);
                    }

                    if (!(string.IsNullOrEmpty(_functionName) || _functionName[0] == '0' /*address*/))
                    {
                        pinfo[0].bstrFunction = _functionName;
                        pinfo[0].dwFields |= enum_CONTEXT_INFO_FIELDS.CIF_FUNCTION;
                    }
                }
                if ((dwFields & enum_CONTEXT_INFO_FIELDS.CIF_FUNCTIONOFFSET) != 0) { }

                return Constants.S_OK;
            }
            catch (MIException e)
            {
                return e.HResult;
            }
            catch (Exception e)
            {
                return EngineUtils.UnexpectedException(e);
            }
        }
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

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