コード例 #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);
        }
コード例 #2
0
        public void ParseAddressFromDecString()
        {
            const string INPUT    = "12345";
            const ulong  EXPECTED = 12345;
            ulong        output;

            Assert.AreEqual(true, DebugEngineUtil.GetAddressFromString(INPUT, out output));
            Assert.AreEqual(EXPECTED, output);
        }
コード例 #3
0
        public void ParseAddressFromHexString()
        {
            const string INPUT    = "0xdeadbeef";
            const ulong  EXPECTED = 0xdeadbeef;
            ulong        output;

            Assert.AreEqual(true, DebugEngineUtil.GetAddressFromString(INPUT, out output));
            Assert.AreEqual(EXPECTED, output);
        }
コード例 #4
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);
        }
コード例 #5
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);
        }