Skip to content

Commit 503df4d

Browse files
author
Rakesh Ganesh
committed
MIEngine: Introduce --thread and --frame options
Remove -thread-select and -stack-select-frame and introduce --thread and --frame options instead. It is general recommendation to not use -thread-select and -stack-select-frame and use --thread and --frame instead. More info can be found here: https://sourceware.org/gdb/onlinedocs/gdb/Context-management.html And here are the deprecation notes: -thread-select -thread-select: https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Thread-Commands.html#GDB_002fMI-Thread-Commands -stack-select-frame -stack-select-frame: https://sourceware.org/gdb/onlinedocs/gdb/GDB_002fMI-Stack-Manipulation.html#GDB_002fMI-Stack-Manipulation Signed-off-by: intel-rganesh rakesh.ganesh@intel.com
1 parent 1b18d41 commit 503df4d

4 files changed

Lines changed: 83 additions & 40 deletions

File tree

src/MICore/CommandFactories/MICommandFactory.cs

Lines changed: 38 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ public abstract class MICommandFactory
5454

5555
public abstract string Name { get; }
5656

57+
internal string Version { get; set; }
58+
5759
public static MICommandFactory GetInstance(MIMode mode, Debugger debugger)
5860
{
5961
MICommandFactory commandFactory;
@@ -119,16 +121,18 @@ public virtual async Task<Results> ThreadInfo(uint? threadid = null)
119121

120122
public async Task<Results> StackInfoDepth(int threadId, int maxDepth = 1000, ResultClass resultClass = ResultClass.done)
121123
{
122-
string command = string.Format(CultureInfo.InvariantCulture, @"-stack-info-depth {0}", maxDepth);
123-
Results results = await ThreadCmdAsync(command, resultClass, threadId);
124+
string command = "-stack-info-depth";
125+
string args = string.Format(CultureInfo.InvariantCulture, $@"{maxDepth}");
126+
Results results = await ThreadCmdAsync(command, args, resultClass, threadId);
124127

125128
return results;
126129
}
127130

128131
public async Task<TupleValue[]> StackListFrames(int threadId, uint lowFrameLevel, uint highFrameLevel = 1000)
129132
{
130-
string command = string.Format(CultureInfo.InvariantCulture, @"-stack-list-frames {0} {1}", lowFrameLevel, highFrameLevel);
131-
Results results = await ThreadCmdAsync(command, ResultClass.done, threadId);
133+
string command = "-stack-list-frames";
134+
string args = string.Format(CultureInfo.InvariantCulture, $@"{lowFrameLevel} {highFrameLevel}");
135+
Results results = await ThreadCmdAsync(command, args, ResultClass.done, threadId);
132136

133137
ListValue list = results.Find<ListValue>("stack");
134138
if (list is ResultListValue)
@@ -164,9 +168,10 @@ public async Task<Results> StackInfoFrame()
164168
/// <returns></returns>
165169
public async Task<ResultValue> StackListLocals(PrintValue printValues, int threadId, uint frameLevel)
166170
{
167-
string cmd = string.Format(CultureInfo.InvariantCulture, @"-stack-list-locals {0}", (int)printValues);
171+
string cmd = "-stack-list-locals";
172+
string args = string.Format(CultureInfo.InvariantCulture, $@"{(int)printValues}");
168173

169-
Results localsResults = await ThreadFrameCmdAsync(cmd, ResultClass.done, threadId, frameLevel);
174+
Results localsResults = await ThreadFrameCmdAsync(cmd, args, ResultClass.done, threadId, frameLevel);
170175
return localsResults.Find("locals");
171176
}
172177

@@ -180,8 +185,9 @@ public async Task<ResultValue> StackListLocals(PrintValue printValues, int threa
180185
/// <returns>This returns an array of results of frames, which contains a level and an args array. </returns>
181186
public virtual async Task<TupleValue[]> StackListArguments(PrintValue printValues, int threadId, uint lowFrameLevel, uint hiFrameLevel)
182187
{
183-
string cmd = string.Format(CultureInfo.InvariantCulture, @"-stack-list-arguments {0} {1} {2}", (int)printValues, lowFrameLevel, hiFrameLevel);
184-
Results argumentsResults = await ThreadCmdAsync(cmd, ResultClass.done, threadId);
188+
string command = "-stack-list-arguments";
189+
string args = string.Format(CultureInfo.InvariantCulture, $@"{(int)printValues} {lowFrameLevel} {hiFrameLevel}");
190+
Results argumentsResults = await ThreadCmdAsync(command, args, ResultClass.done, threadId);
185191

186192
return argumentsResults.Find<ListValue>("stack-args").IsEmpty()
187193
? new TupleValue[0]
@@ -213,9 +219,9 @@ public async Task<ListValue> StackListArguments(PrintValue printValues, int thre
213219
/// <returns>Returns an array of results for variables</returns>
214220
public async Task<ValueListValue> StackListVariables(PrintValue printValues, int threadId, uint frameLevel)
215221
{
216-
string cmd = string.Format(CultureInfo.InvariantCulture, @"-stack-list-variables {0}", (int)printValues);
217-
218-
Results variablesResults = await ThreadFrameCmdAsync(cmd, ResultClass.done, threadId, frameLevel);
222+
string cmd = "-stack-list-variables";
223+
string args = string.Format(CultureInfo.InvariantCulture, $@"{(int)printValues}");
224+
Results variablesResults = await ThreadFrameCmdAsync(cmd, args, ResultClass.done, threadId, frameLevel);
219225
return variablesResults.Find<ValueListValue>("variables");
220226
}
221227

@@ -226,31 +232,36 @@ public async Task<ValueListValue> StackListVariables(PrintValue printValues, int
226232
public async Task ExecStep(int threadId, ResultClass resultClass = ResultClass.running)
227233
{
228234
string command = "-exec-step";
229-
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
235+
string args = string.Empty;
236+
await ThreadFrameCmdAsync(command, args, resultClass, threadId, 0);
230237
}
231238

232239
public async Task ExecNext(int threadId, ResultClass resultClass = ResultClass.running)
233240
{
234241
string command = "-exec-next";
235-
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
242+
string args = string.Empty;
243+
await ThreadFrameCmdAsync(command, args, resultClass, threadId, 0);
236244
}
237245

238246
public async Task ExecFinish(int threadId, ResultClass resultClass = ResultClass.running)
239247
{
240248
string command = "-exec-finish";
241-
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
249+
string args = string.Empty;
250+
await ThreadFrameCmdAsync(command, args, resultClass, threadId, 0);
242251
}
243252

244253
public async Task ExecStepInstruction(int threadId, ResultClass resultClass = ResultClass.running)
245254
{
246255
string command = "-exec-step-instruction";
247-
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
256+
string args = string.Empty;
257+
await ThreadFrameCmdAsync(command, args, resultClass, threadId, 0);
248258
}
249259

250260
public async Task ExecNextInstruction(int threadId, ResultClass resultClass = ResultClass.running)
251261
{
252262
string command = "-exec-next-instruction";
253-
await ThreadFrameCmdAsync(command, resultClass, threadId, 0);
263+
string args = string.Empty;
264+
await ThreadFrameCmdAsync(command, args, resultClass, threadId, 0);
254265
}
255266

256267
/// <summary>
@@ -296,15 +307,17 @@ public async Task<string[]> DataListRegisterNames()
296307

297308
public async Task<TupleValue[]> DataListRegisterValues(int threadId)
298309
{
299-
string command = "-data-list-register-values x";
300-
Results results = await ThreadCmdAsync(command, ResultClass.done, threadId);
310+
string command = "-data-list-register-values";
311+
string args = "x";
312+
Results results = await ThreadCmdAsync(command, args, ResultClass.done, threadId);
301313
return results.Find<ValueListValue>("register-values").AsArray<TupleValue>();
302314
}
303315

304316
public async Task<string> DataEvaluateExpression(string expr, int threadId, uint frame)
305317
{
306-
string command = "-data-evaluate-expression \"" + expr + "\"";
307-
Results results = await ThreadFrameCmdAsync(command, ResultClass.None, threadId, frame);
318+
string command = "-data-evaluate-expression";
319+
string args = $"\"{expr}\"";
320+
Results results = await ThreadFrameCmdAsync(command, args, ResultClass.None, threadId, frame);
308321
return results.FindString("value");
309322
}
310323

@@ -344,8 +357,9 @@ public virtual Task<bool> SetStepFiltering(bool enabled)
344357
public virtual async Task<Results> VarCreate(string expression, int threadId, uint frameLevel, enum_EVALFLAGS dwFlags, ResultClass resultClass = ResultClass.done)
345358
{
346359
string quoteEscapedExpression = EscapeQuotes(HandleInvalidChars(expression));
347-
string command = string.Format(CultureInfo.InvariantCulture, "-var-create - * \"{0}\"", quoteEscapedExpression);
348-
Results results = await ThreadFrameCmdAsync(command, resultClass, threadId, frameLevel);
360+
string command = "-var-create";
361+
string args = string.Format(CultureInfo.InvariantCulture, $" - * \"{quoteEscapedExpression}\"");
362+
Results results = await ThreadFrameCmdAsync(command, args, resultClass, threadId, frameLevel);
349363

350364
return results;
351365
}
@@ -646,8 +660,8 @@ internal string HandleInvalidChars(string str)
646660

647661
#region Other
648662

649-
abstract protected Task<Results> ThreadFrameCmdAsync(string command, ResultClass expectedResultClass, int threadId, uint frameLevel);
650-
abstract protected Task<Results> ThreadCmdAsync(string command, ResultClass expectedResultClass, int threadId);
663+
abstract protected Task<Results> ThreadFrameCmdAsync(string command, string args, ResultClass expectedResultClass, int threadId, uint frameLevel);
664+
abstract protected Task<Results> ThreadCmdAsync(string command, string args, ResultClass expectedResultClass, int threadId);
651665

652666
abstract public string GetSetEnvironmentVariableCommand(string name, string value);
653667

src/MICore/CommandFactories/gdb.cs

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -48,24 +48,37 @@ public override bool AllowCommandsWhileRunning()
4848
return false;
4949
}
5050

51-
protected override async Task<Results> ThreadFrameCmdAsync(string command, ResultClass expectedResultClass, int threadId, uint frameLevel)
51+
protected override async Task<Results> ThreadFrameCmdAsync(string command, string args, ResultClass expectedResultClass, int threadId, uint frameLevel)
5252
{
5353
// first aquire an exclusive lock. This is used as we don't want to fight with other commands that also require the current
5454
// thread to be set to a particular value
5555
ExclusiveLockToken lockToken = await _debugger.CommandLock.AquireExclusive();
5656

5757
try
5858
{
59-
await ThreadSelect(threadId, lockToken);
60-
await StackSelectFrame(frameLevel, lockToken);
59+
int.TryParse(Version.Split('.').FirstOrDefault(), out int gdbMainVersion);
60+
61+
string threadFrameCommand;
62+
// With source code of gdb 7.0.0, the --thread and --frame options were introduced and -thread-select and
63+
// -stack-select-frame were deprecated
64+
if (gdbMainVersion < 7)
65+
{
66+
await ThreadSelect(threadId, lockToken);
67+
await StackSelectFrame(frameLevel, lockToken);
68+
threadFrameCommand = string.Format(CultureInfo.InvariantCulture, $@"{command} {args}");
69+
}
70+
else
71+
{
72+
threadFrameCommand = string.Format(CultureInfo.InvariantCulture, $@"{command} --thread {threadId} --frame {frameLevel} {args}");
73+
}
6174

6275
// Before we execute the provided command, we need to switch to a shared lock. This is because the provided
6376
// command may be an expression evaluation command which could be long running, and we don't want to hold the
6477
// exclusive lock during this.
6578
lockToken.ConvertToSharedLock();
6679
lockToken = null;
6780

68-
return await _debugger.CmdAsync(command, expectedResultClass);
81+
return await _debugger.CmdAsync(threadFrameCommand, expectedResultClass);
6982
}
7083
finally
7184
{
@@ -82,23 +95,36 @@ protected override async Task<Results> ThreadFrameCmdAsync(string command, Resul
8295
}
8396
}
8497

85-
protected override async Task<Results> ThreadCmdAsync(string command, ResultClass expectedResultClass, int threadId)
98+
protected override async Task<Results> ThreadCmdAsync(string command, string args, ResultClass expectedResultClass, int threadId)
8699
{
87100
// first aquire an exclusive lock. This is used as we don't want to fight with other commands that also require the current
88101
// thread to be set to a particular value
89102
ExclusiveLockToken lockToken = await _debugger.CommandLock.AquireExclusive();
90103

91104
try
92105
{
93-
await ThreadSelect(threadId, lockToken);
106+
int.TryParse(Version.Split('.').FirstOrDefault(), out int gdbMainVersion);
107+
108+
string threadCommand;
109+
// With source code of gdb 7.0.0, the --thread option was introduced and -thread-select
110+
// was deprecated
111+
if (gdbMainVersion < 7)
112+
{
113+
await ThreadSelect(threadId, lockToken);
114+
threadCommand = string.Format(CultureInfo.InvariantCulture, $@"{command} {args}");
115+
}
116+
else
117+
{
118+
threadCommand = string.Format(CultureInfo.InvariantCulture, $@"{command} --thread {threadId} {args}"); ;
119+
}
94120

95121
// Before we execute the provided command, we need to switch to a shared lock. This is because the provided
96122
// command may be an expression evaluation command which could be long running, and we don't want to hold the
97123
// exclusive lock during this.
98124
lockToken.ConvertToSharedLock();
99125
lockToken = null;
100126

101-
return await _debugger.CmdAsync(command, expectedResultClass);
127+
return await _debugger.CmdAsync(threadCommand, expectedResultClass);
102128
}
103129
finally
104130
{
@@ -301,12 +327,13 @@ public override async Task Catch(string name, bool onlyOnce = false, ResultClass
301327

302328
public override async Task<string[]> AutoComplete(string command, int threadId, uint frameLevel)
303329
{
304-
command = "-complete \"" + command + "\"";
330+
string cmd = "-complete";
331+
string args = $"\"{command}\"";
305332
Results res;
306333
if (threadId == -1)
307-
res = await _debugger.CmdAsync(command, ResultClass.done);
334+
res = await _debugger.CmdAsync($"{cmd} {args}", ResultClass.done);
308335
else
309-
res = await ThreadFrameCmdAsync(command, ResultClass.done, threadId, frameLevel);
336+
res = await ThreadFrameCmdAsync(cmd, args, ResultClass.done, threadId, frameLevel);
310337

311338
var matchlist = res.Find<ValueListValue>("matches");
312339

src/MICore/CommandFactories/lldb.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,10 @@ public async override Task<StringBuilder> BuildBreakInsert(string condition, boo
7676

7777
public override async Task<Results> VarCreate(string expression, int threadId, uint frameLevel, enum_EVALFLAGS dwFlags, ResultClass resultClass = ResultClass.done)
7878
{
79+
string command = "-var-create";
7980
string quoteEscapedExpression = EscapeQuotes(expression);
80-
string command = string.Format(CultureInfo.InvariantCulture, "-var-create - - \"{0}\"", quoteEscapedExpression); // use '-' to indicate that "--frame" should be used to determine the frame number
81-
Results results = await ThreadFrameCmdAsync(command, resultClass, threadId, frameLevel);
81+
string args = string.Format(CultureInfo.InvariantCulture, $"- - \"{quoteEscapedExpression}\""); // use '-' to indicate that "--frame" should be used to determine the frame number
82+
Results results = await ThreadFrameCmdAsync(command, args, resultClass, threadId, frameLevel);
8283

8384
return results;
8485
}
@@ -94,16 +95,16 @@ public override async Task<Results> VarListChildren(string variableReference, en
9495
return results;
9596
}
9697

97-
protected override async Task<Results> ThreadFrameCmdAsync(string command, ResultClass exepctedResultClass, int threadId, uint frameLevel)
98+
protected override async Task<Results> ThreadFrameCmdAsync(string command, string args, ResultClass exepctedResultClass, int threadId, uint frameLevel)
9899
{
99-
string threadFrameCommand = string.Format(CultureInfo.InvariantCulture, @"{0} --thread {1} --frame {2}", command, threadId, frameLevel);
100+
string threadFrameCommand = string.Format(CultureInfo.InvariantCulture, $@"{command} {args} --thread {threadId} --frame {frameLevel}");
100101

101102
return await _debugger.CmdAsync(threadFrameCommand, exepctedResultClass);
102103
}
103104

104-
protected override async Task<Results> ThreadCmdAsync(string command, ResultClass expectedResultClass, int threadId)
105+
protected override async Task<Results> ThreadCmdAsync(string command, string args, ResultClass expectedResultClass, int threadId)
105106
{
106-
string threadCommand = string.Format(CultureInfo.InvariantCulture, @"{0} --thread {1}", command, threadId);
107+
string threadCommand = string.Format(CultureInfo.InvariantCulture, $@"{command} {args} --thread {threadId}");
107108

108109
return await _debugger.CmdAsync(threadCommand, expectedResultClass);
109110
}

src/MICore/Debugger.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -979,6 +979,7 @@ public void OnDebuggerProcessExit(/*OPTIONAL*/ string exitCode)
979979
{
980980
MIDebuggerInitializeFailedException exception;
981981
string version = GdbVersionFromLog();
982+
MICommandFactory.Version = version;
982983

983984
// We can't use IsMinGW or IsCygwin because we never connected to the debugger
984985
bool isMinGWOrCygwin = _launchOptions is LocalLaunchOptions &&

0 commit comments

Comments
 (0)