public GdbCommandResult RunCommand(string command, params string[] args) { lock (gdbLock) { lock (syncLock) { lastResult = null; lock (eventLock) { running = true; } if (logGdb) { Console.WriteLine("gdb<: " + command + " " + string.Join(" ", args)); } sin.WriteLine(command + " " + string.Join(" ", args)); if (!Monitor.Wait(syncLock, 4000)) { throw new InvalidOperationException("Command execution timeout."); } if (lastResult.Status == CommandStatus.Error) { throw new InvalidOperationException(lastResult.ErrorMessage); } return(lastResult); } } }
bool CheckBreakpoint(int handle) { BreakEventInfo binfo; if (!breakpoints.TryGetValue(handle, out binfo)) { return(true); } Breakpoint bp = (Breakpoint)binfo.BreakEvent; if (!string.IsNullOrEmpty(bp.ConditionExpression) && bp.BreakIfConditionChanges) { // Update the condition expression GdbCommandResult res = RunCommand("-data-evaluate-expression", Escape(bp.ConditionExpression)); string val = res.GetValue("value"); RunCommand("-break-condition", handle.ToString(), "(" + bp.ConditionExpression + ") != " + val); } if (bp.HitAction == HitAction.PrintExpression) { GdbCommandResult res = RunCommand("-data-evaluate-expression", Escape(bp.TraceExpression)); string val = res.GetValue("value"); NotifyBreakEventUpdate(binfo, 0, val); return(false); } return(true); }
public StackFrame[] GetStackFrames(int firstIndex, int lastIndex) { List <StackFrame> frames = new List <StackFrame> (); if (firstIndex == 0 && firstFrame != null) { frames.Add(firstFrame); firstIndex++; } if (lastIndex >= fcount) { lastIndex = fcount - 1; } if (firstIndex > lastIndex) { return(frames.ToArray()); } session.SelectThread(threadId); GdbCommandResult res = session.RunCommand("-stack-list-frames", firstIndex.ToString(), lastIndex.ToString()); ResultData stack = res.GetObject("stack"); for (int n = 0; n < stack.Count; n++) { ResultData frd = stack.GetObject(n); frames.Add(CreateFrame(frd.GetObject("frame"))); } return(frames.ToArray()); }
protected override Backtrace OnGetThreadBacktrace(long processId, long threadId) { ResultData data = SelectThread(threadId); GdbCommandResult res = RunCommand("-stack-info-depth"); int fcount = int.Parse(res.GetValue("depth")); GdbBacktrace bt = new GdbBacktrace(this, threadId, fcount, data != null ? data.GetObject("frame") : null); return(new Backtrace(bt)); }
void ProcessOutput(string line) { if (logGdb) { Console.WriteLine("dbg>: '" + line + "'"); } switch (line [0]) { case '^': lock (syncLock) { lastResult = new GdbCommandResult(line); running = (lastResult.Status == CommandStatus.Running); Monitor.PulseAll(syncLock); } break; case '~': case '&': if (line.Length > 1 && line[1] == '"') { line = line.Substring(2, line.Length - 5); } ThreadPool.QueueUserWorkItem(delegate { OnTargetOutput(false, line + "\n"); }); break; case '*': GdbEvent ev; lock (eventLock) { running = false; ev = new GdbEvent(line); string ti = ev.GetValue("thread-id"); if (ti != null && ti != "all") { currentThread = activeThread = int.Parse(ti); } Monitor.PulseAll(eventLock); if (internalStop) { internalStop = false; return; } } ThreadPool.QueueUserWorkItem(delegate { try { HandleEvent(ev); } catch (Exception ex) { Console.WriteLine(ex); } }); break; } }
ObjectValue CreateVarObject(string exp) { try { session.SelectThread(threadId); exp = exp.Replace("\"", "\\\""); GdbCommandResult res = session.RunCommand("-var-create", "-", "*", "\"" + exp + "\""); string vname = res.GetValue("name"); session.RegisterTempVariableObject(vname); return(CreateObjectValue(exp, res)); } catch { return(ObjectValue.CreateUnknown(exp)); } }
public ObjectValue[] GetParameters(int frameIndex, EvaluationOptions options) { List <ObjectValue> values = new List <ObjectValue> (); SelectFrame(frameIndex); GdbCommandResult res = session.RunCommand("-stack-list-arguments", "0", frameIndex.ToString(), frameIndex.ToString()); foreach (ResultData data in res.GetObject("stack-args").GetObject(0).GetObject("frame").GetObject("args")) { values.Add(CreateVarObject(data.GetValue("name"))); } return(values.ToArray()); }
protected override void OnFinish() { SelectThread(activeThread); GdbCommandResult res = RunCommand("-stack-info-depth", "2"); if (res.GetValue("depth") == "1") { RunCommand("-exec-continue"); } else { RunCommand("-stack-select-frame", "0"); RunCommand("-exec-finish"); } }
public ObjectValue[] GetLocalVariables(int frameIndex, EvaluationOptions options) { List <ObjectValue> values = new List <ObjectValue> (); SelectFrame(frameIndex); GdbCommandResult res = session.RunCommand("-stack-list-locals", "0"); foreach (ResultData data in res.GetObject("locals")) { values.Add(CreateVarObject(data.GetValue("name"))); } return(values.ToArray()); }
public ObjectValue[] GetChildren(ObjectPath path, int index, int count, EvaluationOptions options) { List <ObjectValue> children = new List <ObjectValue> (); session.SelectThread(threadId); GdbCommandResult res = session.RunCommand("-var-list-children", "2", path.Join(".")); ResultData cdata = res.GetObject("children"); // The response may not contain the "children" list at all. if (cdata == null) { return(children.ToArray()); } if (index == -1) { index = 0; count = cdata.Count; } for (int n = index; n < cdata.Count && n < index + count; n++) { ResultData data = cdata.GetObject(n); ResultData child = data.GetObject("child"); string name = child.GetValue("exp"); if (name.Length > 0 && char.IsNumber(name [0])) { name = "[" + name + "]"; } // C++ structures may contain typeless children named // "public", "private" and "protected". if (child.GetValue("type") == null) { ObjectPath childPath = new ObjectPath(child.GetValue("name").Split('.')); ObjectValue[] subchildren = GetChildren(childPath, -1, -1, options); children.AddRange(subchildren); } else { ObjectValue val = CreateObjectValue(name, child); children.Add(val); } } return(children.ToArray()); }
void FireTargetEvent(TargetEventType type, ResultData curFrame) { UpdateHitCountData(); TargetEventArgs args = new TargetEventArgs(type); if (type != TargetEventType.TargetExited) { GdbCommandResult res = RunCommand("-stack-info-depth"); int fcount = int.Parse(res.GetValue("depth")); GdbBacktrace bt = new GdbBacktrace(this, activeThread, fcount, curFrame); args.Backtrace = new Backtrace(bt); args.Thread = GetThread(activeThread); } OnTargetEvent(args); }
void UpdateHitCountData() { foreach (BreakEventInfo bp in breakpointsWithHitCount) { GdbCommandResult res = RunCommand("-break-info", bp.Handle.ToString()); string val = res.GetObject("BreakpointTable").GetObject("body").GetObject(0).GetObject("bkpt").GetValue("ignore"); if (val != null) { NotifyBreakEventUpdate(bp, int.Parse(val), null); } else { NotifyBreakEventUpdate(bp, 0, null); } } breakpointsWithHitCount.Clear(); }
public GdbCommandResult RunCommand (string command, params string[] args) { lock (gdbLock) { lock (syncLock) { lastResult = null; lock (eventLock) { running = true; } command = command + " " + string.Join (" ", args); if (logGdb) LoggingService.LogInfo ("gdb<: {0}",command); sin.WriteLine (command); if (!Monitor.Wait (syncLock, CommandTimeout)) throw new GdbException (command,"Command execution timeout."); if (lastResult.Status == CommandStatus.Error) throw new GdbException (command,lastResult.ErrorMessage); return lastResult; } } }
protected override object OnInsertBreakEvent(BreakEvent be, bool activate) { Breakpoint bp = be as Breakpoint; if (bp == null) { return(null); } lock (gdbLock) { bool dres = InternalStop(); try { string extraCmd = string.Empty; if (bp.HitCount > 0) { extraCmd += "-i " + bp.HitCount; breakpointsWithHitCount.Add(bp); } if (!string.IsNullOrEmpty(bp.ConditionExpression)) { if (!bp.BreakIfConditionChanges) { extraCmd += " -c " + bp.ConditionExpression; } } // Breakpoint locations must be double-quoted if files contain spaces. // For example: -break-insert "\"C:/Documents and Settings/foo.c\":17" RunCommand("-environment-directory", Escape(Path.GetDirectoryName(bp.FileName))); GdbCommandResult res = null; string errorMsg = null; try { res = RunCommand("-break-insert", extraCmd.Trim(), Escape(Escape(bp.FileName) + ":" + bp.Line)); } catch (Exception ex) { errorMsg = ex.Message; } if (res == null) { try { res = RunCommand("-break-insert", extraCmd.Trim(), Escape(Escape(Path.GetFileName(bp.FileName)) + ":" + bp.Line)); } catch { // Ignore } } if (res == null) { OnDebuggerOutput(true, "Could not set breakpoint: " + errorMsg); return(null); } int bh = res.GetObject("bkpt").GetInt("number"); if (!activate) { RunCommand("-break-disable", bh.ToString()); } breakpoints [bh] = bp; return(bh); } finally { InternalResume(dres); } } }
public GdbCommandResult RunCommand (string command, params string[] args) { lock (gdbLock) { lock (syncLock) { lastResult = null; lock (eventLock) { running = true; } if (logGdb) Console.WriteLine ("gdb<: " + command + " " + string.Join (" ", args)); sin.WriteLine (command + " " + string.Join (" ", args)); if (!Monitor.Wait (syncLock, 4000)) throw new InvalidOperationException ("Command execution timeout."); if (lastResult.Status == CommandStatus.Error) throw new InvalidOperationException (lastResult.ErrorMessage); return lastResult; } } }
void ProcessOutput (string line) { if (logGdb) Console.WriteLine ("dbg>: '" + line + "'"); switch (line [0]) { case '^': lock (syncLock) { lastResult = new GdbCommandResult (line); running = (lastResult.Status == CommandStatus.Running); Monitor.PulseAll (syncLock); } break; case '~': case '&': if (line.Length > 1 && line[1] == '"') line = line.Substring (2, line.Length - 5); ThreadPool.QueueUserWorkItem (delegate { OnTargetOutput (false, line + "\n"); }); break; case '*': GdbEvent ev; lock (eventLock) { running = false; ev = new GdbEvent (line); string ti = ev.GetValue ("thread-id"); if (ti != null && ti != "all") currentThread = activeThread = int.Parse (ti); Monitor.PulseAll (eventLock); if (internalStop) { internalStop = false; return; } } ThreadPool.QueueUserWorkItem (delegate { try { HandleEvent (ev); } catch (Exception ex) { Console.WriteLine (ex); } }); break; } }
public CompletionData GetExpressionCompletionData(int frameIndex, string exp) { SelectFrame(frameIndex); bool pointer = exp.EndsWith("->"); int i; if (pointer || exp.EndsWith(".")) { exp = exp.Substring(0, exp.Length - (pointer ? 2 : 1)); i = 0; while (i < exp.Length) { ObjectValue val = CreateVarObject(exp); if (!val.IsUnknown && !val.IsError) { CompletionData data = new CompletionData(); foreach (ObjectValue cv in val.GetAllChildren()) { data.Items.Add(new CompletionItem(cv.Name, cv.Flags)); } data.ExpressionLenght = 0; return(data); } i++; } return(null); } i = exp.Length - 1; bool lastWastLetter = false; while (i >= 0) { char c = exp [i--]; if (!char.IsLetterOrDigit(c) && c != '_') { break; } lastWastLetter = !char.IsDigit(c); } if (lastWastLetter) { string partialWord = exp.Substring(i + 1); CompletionData cdata = new CompletionData(); cdata.ExpressionLenght = partialWord.Length; // Local variables GdbCommandResult res = session.RunCommand("-stack-list-locals", "0"); foreach (ResultData data in res.GetObject("locals")) { string name = data.GetValue("name"); if (name.StartsWith(partialWord)) { cdata.Items.Add(new CompletionItem(name, ObjectValueFlags.Variable)); } } // Parameters res = session.RunCommand("-stack-list-arguments", "0", frameIndex.ToString(), frameIndex.ToString()); foreach (ResultData data in res.GetObject("stack-args").GetObject(0).GetObject("frame").GetObject("args")) { string name = data.GetValue("name"); if (name.StartsWith(partialWord)) { cdata.Items.Add(new CompletionItem(name, ObjectValueFlags.Parameter)); } } if (cdata.Items.Count > 0) { return(cdata); } } return(null); }
protected override BreakEventInfo OnInsertBreakEvent(BreakEvent be) { Breakpoint bp = be as Breakpoint; if (bp == null) { throw new NotSupportedException(); } BreakEventInfo bi = new BreakEventInfo(); lock (gdbLock) { bool dres = InternalStop(); try { string extraCmd = string.Empty; if (bp.HitCount > 0) { extraCmd += "-i " + bp.HitCount; breakpointsWithHitCount.Add(bi); } if (!string.IsNullOrEmpty(bp.ConditionExpression)) { if (!bp.BreakIfConditionChanges) { extraCmd += " -c " + bp.ConditionExpression; } } // Breakpoint locations must be double-quoted if files contain spaces. // For example: -break-insert "\"C:/Documents and Settings/foo.c\":17" RunCommand("-environment-directory", Escape(Path.GetDirectoryName(bp.FileName))); GdbCommandResult res = null; string errorMsg = null; try { res = RunCommand("-break-insert", extraCmd.Trim(), Escape(Escape(bp.FileName) + ":" + bp.Line)); } catch (Exception ex) { errorMsg = ex.Message; } if (res == null) { try { res = RunCommand("-break-insert", extraCmd.Trim(), Escape(Escape(Path.GetFileName(bp.FileName)) + ":" + bp.Line)); } catch { // Ignore } } if (res == null) { bi.SetStatus(BreakEventStatus.Invalid, errorMsg); return(bi); } int bh = res.GetObject("bkpt").GetInt("number"); if (!be.Enabled) { RunCommand("-break-disable", bh.ToString()); } breakpoints [bh] = bi; bi.Handle = bh; bi.SetStatus(BreakEventStatus.Bound, null); return(bi); } finally { InternalResume(dres); } } }
protected virtual void ProcessOutput (string line) { if (logGdb) LoggingService.LogInfo ("dbg>: {0}",line); switch (line [0]) { case '^': lock (syncLock) { lastResult = new GdbCommandResult (line); running = (lastResult.Status == CommandStatus.Running); Monitor.PulseAll (syncLock); } break; case '~': case '&': if (line.Length > 1 && line[1] == '"') line = line.Substring (2, line.Length - 5); Ide.DispatchService.GuiDispatch(delegate { OnTargetOutput (false, line + "\n"); }); break; case '*': GdbEvent ev; lock (eventLock) { running = false; ev = new GdbEvent (line); string ti = ev.GetValueString ("thread-id"); if (ti != null && ti != "all") currentThread = activeThread = int.Parse (ti); Monitor.PulseAll (eventLock); if (internalStop) { internalStop = false; return; } } ThreadPool.QueueUserWorkItem (delegate { try { HandleEvent (ev); } catch (Exception ex) { LoggingService.LogError("Error while processing gdb output", ex); } }); break; } }