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); } }
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); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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; } }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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 GetInfoNone() { var contextInfo = new CONTEXT_INFO[1]; Assert.AreEqual(VSConstants.S_OK, memoryContext.GetInfo(0, contextInfo)); Assert.AreEqual(0, (uint)contextInfo[0].dwFields); }
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); }
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)); }
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); }
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); }
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); } }
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); }
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); } }
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); }
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; }
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)); }
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 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; } }
// 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); } }
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; }
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; } }
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); }
// 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; } }
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); }
// 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; }
public int GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo) { return VSConstants.E_FAIL; }
/// <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; }
int IDebugCodeContext2.GetInfo(enum_CONTEXT_INFO_FIELDS dwFields, CONTEXT_INFO[] pinfo) { return IDebugMemoryContext2.GetInfo(dwFields, pinfo); }
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; }
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(); }
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); }
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; }
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; }
// 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; } }