Skip to content

Commit af00945

Browse files
authored
[lldb] Fix thread backtrace --count (#83602)
The help output for `thread backtrace` specifies that you can pass -1 to `--count` to display all the frames. ``` -c <count> ( --count <count> ) How many frames to display (-1 for all) ``` However, that doesn't work: ``` (lldb) thread backtrace --count -1 error: invalid integer value for option 'c' ``` The problem is that we store the option value as an unsigned and the code to parse the string correctly rejects it. There's two ways to fix this: 1. Make `m_count` a signed value so that it accepts negative values and appease the parser. The function that prints the frames takes an unsigned so a negative value will just become a really large positive value, which is what the current implementation relies on. 2. Keep `m_count` unsigned and instead use 0 the magic value to show all frames. I don't really see a point in not showing any frames at all, plus that's already broken (`error: error displaying backtrace for thread: "0x0001"`). This patch implements (2) and at the same time improve the error reporting so that we print the invalid value when we cannot parse it. rdar://123881767
1 parent 00570c3 commit af00945

File tree

3 files changed

+38
-15
lines changed

3 files changed

+38
-15
lines changed

lldb/source/Commands/CommandObjectThread.cpp

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,21 +67,27 @@ class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads {
6767
if (option_arg.getAsInteger(0, m_count)) {
6868
m_count = UINT32_MAX;
6969
error.SetErrorStringWithFormat(
70-
"invalid integer value for option '%c'", short_option);
70+
"invalid integer value for option '%c': %s", short_option,
71+
option_arg.data());
7172
}
73+
// A count of 0 means all frames.
74+
if (m_count == 0)
75+
m_count = UINT32_MAX;
7276
break;
7377
case 's':
7478
if (option_arg.getAsInteger(0, m_start))
7579
error.SetErrorStringWithFormat(
76-
"invalid integer value for option '%c'", short_option);
80+
"invalid integer value for option '%c': %s", short_option,
81+
option_arg.data());
7782
break;
7883
case 'e': {
7984
bool success;
8085
m_extended_backtrace =
8186
OptionArgParser::ToBoolean(option_arg, false, &success);
8287
if (!success)
8388
error.SetErrorStringWithFormat(
84-
"invalid boolean value for option '%c'", short_option);
89+
"invalid boolean value for option '%c': %s", short_option,
90+
option_arg.data());
8591
} break;
8692
default:
8793
llvm_unreachable("Unimplemented option");
@@ -228,9 +234,9 @@ class CommandObjectThreadBacktrace : public CommandObjectIterateOverThreads {
228234
thread->GetIndexID());
229235
return false;
230236
}
231-
if (m_options.m_extended_backtrace) {
232-
if (!INTERRUPT_REQUESTED(GetDebugger(),
233-
"Interrupt skipped extended backtrace")) {
237+
if (m_options.m_extended_backtrace) {
238+
if (!INTERRUPT_REQUESTED(GetDebugger(),
239+
"Interrupt skipped extended backtrace")) {
234240
DoExtendedBacktrace(thread, result);
235241
}
236242
}
@@ -272,8 +278,9 @@ class ThreadStepScopeOptionGroup : public OptionGroup {
272278
bool avoid_no_debug =
273279
OptionArgParser::ToBoolean(option_arg, true, &success);
274280
if (!success)
275-
error.SetErrorStringWithFormat("invalid boolean value for option '%c'",
276-
short_option);
281+
error.SetErrorStringWithFormat(
282+
"invalid boolean value for option '%c': %s", short_option,
283+
option_arg);
277284
else {
278285
m_step_in_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
279286
}
@@ -284,17 +291,19 @@ class ThreadStepScopeOptionGroup : public OptionGroup {
284291
bool avoid_no_debug =
285292
OptionArgParser::ToBoolean(option_arg, true, &success);
286293
if (!success)
287-
error.SetErrorStringWithFormat("invalid boolean value for option '%c'",
288-
short_option);
294+
error.SetErrorStringWithFormat(
295+
"invalid boolean value for option '%c': %s", short_option,
296+
option_arg);
289297
else {
290298
m_step_out_avoid_no_debug = avoid_no_debug ? eLazyBoolYes : eLazyBoolNo;
291299
}
292300
} break;
293301

294302
case 'c':
295303
if (option_arg.getAsInteger(0, m_step_count))
296-
error.SetErrorStringWithFormat("invalid step count '%s'",
297-
option_arg.str().c_str());
304+
error.SetErrorStringWithFormat(
305+
"invalid integer value for option '%c': %s", short_option,
306+
option_arg.data());
298307
break;
299308

300309
case 'm': {

lldb/source/Commands/Options.td

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ let Command = "script add" in {
805805
def script_add_function : Option<"function", "f">, Group<1>,
806806
Arg<"PythonFunction">,
807807
Desc<"Name of the Python function to bind to this command name.">;
808-
def script_add_class : Option<"class", "c">, Groups<[2,3]>,
808+
def script_add_class : Option<"class", "c">, Groups<[2,3]>,
809809
Arg<"PythonClass">,
810810
Desc<"Name of the Python class to bind to this command name.">;
811811
def script_add_help : Option<"help", "h">, Group<1>, Arg<"HelpText">,
@@ -816,7 +816,7 @@ let Command = "script add" in {
816816
EnumArg<"ScriptedCommandSynchronicity">,
817817
Desc<"Set the synchronicity of this command's executions with regard to "
818818
"LLDB event system.">;
819-
def script_add_completion_type : Option<"completion-type", "C">,
819+
def script_add_completion_type : Option<"completion-type", "C">,
820820
Groups<[1,2]>, EnumArg<"CompletionType">,
821821
Desc<"Specify which completion type the command should use - if none is "
822822
"specified, the command won't use auto-completion.">;
@@ -1037,7 +1037,7 @@ let Command = "target stop hook add" in {
10371037

10381038
let Command = "thread backtrace" in {
10391039
def thread_backtrace_count : Option<"count", "c">, Group<1>, Arg<"Count">,
1040-
Desc<"How many frames to display (-1 for all)">;
1040+
Desc<"How many frames to display (0 for all)">;
10411041
def thread_backtrace_start : Option<"start", "s">, Group<1>,
10421042
Arg<"FrameIndex">, Desc<"Frame in which to start the backtrace">;
10431043
def thread_backtrace_extended : Option<"extended", "e">, Group<1>,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# RUN: %clang_host -g %S/Inputs/main.c -o %t
2+
3+
# RUN: not %lldb %t -b -o 'b foo' -o 'r' -o 'thread backtrace --count -1' 2>&1 | FileCheck %s --check-prefix COUNT
4+
# COUNT: error: invalid integer value for option 'c': -1
5+
6+
# RUN: not %lldb %t -b -o 'b foo' -o 'r' -o 'thread backtrace --extended nah' 2>&1 | FileCheck %s --check-prefix EXTENDED
7+
# EXTENDED: error: invalid boolean value for option 'e': nah
8+
9+
# RUN: not %lldb %t -b -o 'b foo' -o 'r' -o 'thread backtrace --start -1' 2>&1 | FileCheck %s --check-prefix START
10+
# START: error: invalid integer value for option 's': -1
11+
12+
# RUN: %lldb %t -b -o 'b foo' -o 'r' -o 'thread backtrace --count 0' | FileCheck %s
13+
# CHECK: frame #0:
14+
# CHECK: frame #1:

0 commit comments

Comments
 (0)