private static IEnumerable <DisasmInstruction> DecodeSourceAnnotatedDisassemblyInstructions(DebuggedProcess process, TupleValue[] items) { foreach (var item in items) { uint line = item.FindUint("line"); string file = process.GetMappedFileFromTuple(item); ValueListValue asm_items = item.Find <ValueListValue>("line_asm_insn"); uint lineOffset = 0; foreach (var asm_item in asm_items.Content) { DisasmInstruction disassemblyData = new DisasmInstruction(); disassemblyData.Addr = asm_item.FindAddr("address"); disassemblyData.AddressString = asm_item.FindString("address"); disassemblyData.Symbol = asm_item.TryFindString("func-name"); disassemblyData.Offset = asm_item.Contains("offset") ? asm_item.FindUint("offset") : 0; disassemblyData.Opcode = asm_item.FindString("inst"); disassemblyData.CodeBytes = asm_item.TryFindString("opcodes"); disassemblyData.Line = line; disassemblyData.File = file; if (lineOffset == 0) { lineOffset = disassemblyData.Offset; // offset to start of current line } disassemblyData.OffsetInLine = disassemblyData.Offset - lineOffset; yield return(disassemblyData); } } }
public DebuggedModule(string id, string name, ValueListValue sections, bool symbolsLoaded, uint loadOrder) { Id = id; Name = name; Sections = new List <Section>(); LoadSections(sections); SymbolsLoaded = symbolsLoaded; SymbolPath = name; // symbols in module _loadOrder = loadOrder; }
public DebuggedModule(string id, string name, ValueListValue sections, bool symbolsLoaded, uint loadOrder) { Id = id; Name = name; Sections = new List<Section>(); LoadSections(sections); SymbolsLoaded = symbolsLoaded; SymbolPath = name; // symbols in module _loadOrder = loadOrder; }
//This method gets the value/type info for the method parameters without creating an MI debugger varialbe for them. For use in the callstack window //NOTE: eval is not called public async Task <List <SimpleVariableInformation> > GetParameterInfoOnly(AD7Thread thread, ThreadContext ctx) { List <SimpleVariableInformation> parameters = new List <SimpleVariableInformation>(); ValueListValue localAndParameters = await MICommandFactory.StackListVariables(PrintValues.SimpleValues, thread.Id, ctx.Level); foreach (var results in localAndParameters.Content.Where(r => r.TryFindString("arg") == "1")) { parameters.Add(new SimpleVariableInformation(results.FindString("name"), /*isParam*/ true, results.FindString("value"), results.FindString("type"))); } return(parameters); }
internal async Task <uint> ReadProcessMemory(ulong address, uint count, byte[] bytes) { string cmd = "-data-read-memory-bytes " + EngineUtils.AsAddr(address) + " " + count.ToString(); Results results = await CmdAsync(cmd, ResultClass.None); if (results.ResultClass == ResultClass.error) { return(uint.MaxValue); } ValueListValue mem = results.Find <ValueListValue>("memory"); if (mem.IsEmpty()) { return(0); } TupleValue res = mem.Content[0] as TupleValue; if (res == null) { return(0); } ulong start = res.FindAddr("begin"); ulong end = res.FindAddr("end"); ulong offset = res.FindAddr("offset"); // for some reason this is formatted as hex string content = res.FindString("contents"); uint toRead = (uint)content.Length / 2; if (toRead > count) { toRead = count; } // ensure the buffer contains the desired bytes. if (start + offset != address) { throw new MIException(Constants.E_FAIL); } for (int pos = 0; pos < toRead; ++pos) { // Decode one byte string strByte = content.Substring(pos * 2, 2); bytes[pos] = Convert.ToByte(strByte, 16); } return(toRead); }
//This method gets the locals and parameters and creates an MI debugger variable for each one so that we can manipulate them (and expand children, etc.) //NOTE: Eval is called internal async Task <List <VariableInformation> > GetLocalsAndParameters(AD7Thread thread, ThreadContext ctx) { List <VariableInformation> variables = new List <VariableInformation>(); ValueListValue localsAndParameters = await MICommandFactory.StackListVariables(PrintValues.NoValues, thread.Id, ctx.Level); foreach (var localOrParamResult in localsAndParameters.Content) { string name = localOrParamResult.FindString("name"); bool isParam = localOrParamResult.TryFindString("arg") == "1"; SimpleVariableInformation simpleInfo = new SimpleVariableInformation(name, isParam); VariableInformation vi = await simpleInfo.CreateMIDebuggerVariable(ctx, Engine, thread); variables.Add(vi); } return(variables); }
private async Task <SourceLineMap> LinesForFile(string file) { string cmd = "-symbol-list-lines " + _process.EscapePath(file); Results results = await _process.CmdAsync(cmd, ResultClass.None); if (results.ResultClass != ResultClass.done) { return(null); } ValueListValue lines = results.Find <ValueListValue>("lines"); SourceLineMap linesMap = new SourceLineMap(lines.Content.Length); for (int i = 0; i < lines.Content.Length; ++i) { ulong addr = lines.Content[i].FindAddr("pc"); uint line = lines.Content[i].FindUint("line"); linesMap.Add(addr, line); } return(linesMap); }
private async Task <SourceLineMap> LinesForFile(string file) { string cmd = "-symbol-list-lines " + _process.EscapeSymbolPath(file); Results results = await _process.CmdAsync(cmd, ResultClass.None); if (results.ResultClass != ResultClass.done) { return(null); } ValueListValue lines = results.Find <ValueListValue>("lines"); SourceLineMap linesMap = new SourceLineMap(lines.Content.Length); for (int i = 0; i < lines.Content.Length; ++i) { ulong addr = lines.Content[i].FindAddr("pc"); uint line = lines.Content[i].FindUint("line"); if (linesMap.ContainsKey(addr)) { // It is actually fairly common for an address to map to more than one line. For instance, // in debug builds destructors can have an entry to line 0 as well as one to the correct line. // Release builds with inlining will hit this very often. // Unforunately, without more context, it is impossible to know which line is the "right" line. // For the inline case, any line will be acceptable. For the destructor case, we should prefer // a non-zero line. if (linesMap[addr].Line == 0) { linesMap.Replace(addr, line); } } else { linesMap.Add(addr, line); } } return(linesMap); }
private void LoadSections(ValueListValue sectionList) { if (sectionList == null) { return; } List <Section> sections = new List <Section>(); foreach (var s in sectionList.Content) { string name = s.FindString("name"); ulong addr = s.FindAddr("addr"); uint size = 0; try { size = s.FindUint("size"); } catch (OverflowException) { //TODO: sometimes for iOS, size is being reported as a number larger than uint //TODO: currnetly, this is only superficial information displayed in the UI. //TODO: so just swallow the exception and show zero. //TODO: this may be a bug in the lldb side } if (addr != INVALID_ADDRESS) { sections.Add(new Section(name, addr, size)); } } if (sections.Count > 0) { Sections = sections; } }
private void LoadSections(ValueListValue sectionList) { if (sectionList == null) { return; } List<Section> sections = new List<Section>(); foreach (var s in sectionList.Content) { string name = s.FindString("name"); ulong addr = s.FindAddr("addr"); uint size = 0; try { size = s.FindUint("size"); } catch (OverflowException) { //TODO: sometimes for iOS, size is being reported as a number larger than uint //TODO: currnetly, this is only superficial information displayed in the UI. //TODO: so just swallow the exception and show zero. //TODO: this may be a bug in the lldb side } if (addr != INVALID_ADDRESS) { sections.Add(new Section(name, addr, size)); } } if (sections.Count > 0) { Sections = sections; } }
private static BindResult EvalBindResult(Results bindResult, AD7PendingBreakpoint pbreak) { string errormsg = "Unknown error"; if (bindResult.ResultClass == ResultClass.error) { if (bindResult.Contains("msg")) { errormsg = bindResult.FindString("msg"); } if (String.IsNullOrWhiteSpace(errormsg)) { errormsg = "Unknown error"; } return(new BindResult(errormsg)); } else if (bindResult.ResultClass != ResultClass.done) { return(new BindResult(errormsg)); } TupleValue bkpt = null; ValueListValue list = null; if (bindResult.Contains("bkpt")) { ResultValue b = bindResult.Find("bkpt"); if (b is TupleValue) { bkpt = b as TupleValue; } else if (b is ValueListValue) { // "<MULTIPLE>" sometimes includes a list of bound breakpoints list = b as ValueListValue; bkpt = list.Content[0] as TupleValue; } } else { // If the source file is not found, "done" is the result without a binding // (the error is sent via an "&" string and hence lost) return(new BindResult(errormsg)); } Debug.Assert(bkpt.FindString("type") == "breakpoint"); string number = bkpt.FindString("number"); string warning = bkpt.TryFindString("warning"); string addr = bkpt.TryFindString("addr"); PendingBreakpoint bp; if (!string.IsNullOrEmpty(warning)) { Debug.Assert(string.IsNullOrEmpty(addr)); return(new BindResult(new PendingBreakpoint(pbreak, number, MIBreakpointState.Pending), warning)); } bp = new PendingBreakpoint(pbreak, number, StringToBreakpointState(addr)); if (list == null) // single breakpoint { BoundBreakpoint bbp = bp.GetBoundBreakpoint(bkpt); if (bbp == null) { return(new BindResult(bp, MICoreResources.Status_BreakpointPending)); } return(new BindResult(bp, bbp)); } else // <MULTIPLE> with list of addresses { BindResult res = new BindResult(bp); for (int i = 1; i < list.Content.Length; ++i) { BoundBreakpoint bbp = bp.GetBoundBreakpoint(list.Content[i] as TupleValue); res.BoundBreakpoints.Add(bbp); } return(res); } }
internal static async Task <BindResult> Bind(string documentName, uint line, uint column, DebuggedProcess process, string condition, AD7PendingBreakpoint pbreak) { string basename = System.IO.Path.GetFileName(documentName); // get basename from Windows path Results bindResult = await process.MICommandFactory.BreakInsert(process.EscapePath(basename), line, condition, ResultClass.None); string errormsg = "Unknown error"; if (bindResult.ResultClass == ResultClass.error) { if (bindResult.Contains("msg")) { errormsg = bindResult.FindString("msg"); } if (String.IsNullOrWhiteSpace(errormsg)) { errormsg = "Unknown error"; } return(new BindResult(errormsg)); } else if (bindResult.ResultClass != ResultClass.done) { return(new BindResult(errormsg)); } TupleValue bkpt = null; ValueListValue list = null; if (bindResult.Contains("bkpt")) { ResultValue b = bindResult.Find("bkpt"); if (b is TupleValue) { bkpt = b as TupleValue; } else if (b is ValueListValue) { // "<MULTIPLE>" sometimes includes a list of bound breakpoints list = b as ValueListValue; bkpt = list.Content[0] as TupleValue; } } else { // If the source file is not found, "done" is the result without a binding // (the error is sent via an "&" string and hence lost) return(new BindResult(errormsg)); } Debug.Assert(bkpt.FindString("type") == "breakpoint"); string number = bkpt.FindString("number"); string addr = bkpt.TryFindString("addr"); PendingBreakpoint bp = new PendingBreakpoint(pbreak, number, StringToBreakpointState(addr)); if (list == null) // single breakpoint { BoundBreakpoint bbp = bp.GetBoundBreakpoint(bkpt); if (bbp == null) { return(new BindResult(bp, MICoreResources.Status_BreakpointPending)); } return(new BindResult(bp, bbp)); } else // <MULTIPLE> with list of addresses { BindResult res = new BindResult(bp); for (int i = 1; i < list.Content.Length; ++i) { BoundBreakpoint bbp = bp.GetBoundBreakpoint(list.Content[i] as TupleValue); res.BoundBreakpoints.Add(bbp); } return(res); } }