Skip to content

Commit 28a6be5

Browse files
committed
[lldb/crashlog] Make interactive mode the new default (llvm#144839)
This patch makes interactive mode as the default when using the crashlog command. It replaces the existing `-i|--interactive` flag with a new `-m|--mode` option, that can either be `interactive` or `batch`. By default, when the option is not explicitely set by the user, the interactive mode is selected, however, lldb will fallback to batch mode if the command interpreter is not interactive or if stdout is not a tty. This also adds some railguards to prevent users from using interactive only options with the batch mode and updates the tests accordingly. rdar://97801509 Differential Revision: https://reviews.llvm.org/D141658 Signed-off-by: Med Ismail Bennani <[email protected]> (cherry picked from commit 7b989ad)
1 parent 3d8c4dc commit 28a6be5

File tree

6 files changed

+85
-55
lines changed

6 files changed

+85
-55
lines changed

lldb/examples/python/crashlog.py

Lines changed: 78 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import concurrent.futures
3232
import contextlib
3333
import datetime
34+
import enum
3435
import json
3536
import os
3637
import platform
@@ -45,7 +46,6 @@
4546
import time
4647
import uuid
4748

48-
4949
print_lock = threading.RLock()
5050

5151
try:
@@ -1585,9 +1585,12 @@ def synchronous(debugger):
15851585
debugger.RunCommandInterpreter(True, False, run_options, 0, False, True)
15861586

15871587

1588-
def CreateSymbolicateCrashLogOptions(
1589-
command_name, description, add_interactive_options
1590-
):
1588+
class CrashLogLoadingMode(str, enum.Enum):
1589+
batch = "batch"
1590+
interactive = "interactive"
1591+
1592+
1593+
def CreateSymbolicateCrashLogOptions(command_name, description):
15911594
usage = "crashlog [options] <FILE> [FILE ...]"
15921595
arg_parser = argparse.ArgumentParser(
15931596
description=description,
@@ -1603,6 +1606,12 @@ def CreateSymbolicateCrashLogOptions(
16031606
help="crash report(s) to symbolicate",
16041607
)
16051608

1609+
arg_parser.add_argument(
1610+
"-m",
1611+
"--mode",
1612+
choices=[mode.value for mode in CrashLogLoadingMode],
1613+
help="change how the symbolicated process and threads are displayed to the user (default: interactive)",
1614+
)
16061615
arg_parser.add_argument(
16071616
"--version",
16081617
"-V",
@@ -1739,36 +1748,35 @@ def CreateSymbolicateCrashLogOptions(
17391748
help=argparse.SUPPRESS,
17401749
default=False,
17411750
)
1742-
if add_interactive_options:
1743-
arg_parser.add_argument(
1744-
"-i",
1745-
"--interactive",
1746-
action="store_true",
1747-
help="parse a crash log and load it in a ScriptedProcess",
1748-
default=False,
1749-
)
1750-
arg_parser.add_argument(
1751-
"-b",
1752-
"--batch",
1753-
action="store_true",
1754-
help="dump symbolicated stackframes without creating a debug session",
1755-
default=True,
1756-
)
1757-
arg_parser.add_argument(
1758-
"--target",
1759-
"-t",
1760-
dest="target_path",
1761-
help="the target binary path that should be used for interactive crashlog (optional)",
1762-
default=None,
1763-
)
1764-
arg_parser.add_argument(
1765-
"--skip-status",
1766-
"-s",
1767-
dest="skip_status",
1768-
action="store_true",
1769-
help="prevent the interactive crashlog to dump the process status and thread backtrace at launch",
1770-
default=False,
1771-
)
1751+
arg_parser.add_argument(
1752+
"--target",
1753+
"-t",
1754+
dest="target_path",
1755+
help="the target binary path that should be used for interactive crashlog (optional)",
1756+
default=None,
1757+
)
1758+
arg_parser.add_argument(
1759+
"--skip-status",
1760+
"-s",
1761+
dest="skip_status",
1762+
action="store_true",
1763+
help="prevent the interactive crashlog to dump the process status and thread backtrace at launch",
1764+
default=False,
1765+
)
1766+
legacy_group = arg_parser.add_mutually_exclusive_group()
1767+
legacy_group.add_argument(
1768+
"-i",
1769+
"--interactive",
1770+
action="store_true",
1771+
help=argparse.SUPPRESS,
1772+
)
1773+
legacy_group.add_argument(
1774+
"-b",
1775+
"--batch",
1776+
action="store_true",
1777+
help=argparse.SUPPRESS,
1778+
)
1779+
17721780
return arg_parser
17731781

17741782

@@ -1781,7 +1789,7 @@ def CrashLogOptionParser():
17811789
created that has all of the shared libraries loaded at the load addresses found in the crash log file. This allows
17821790
you to explore the program as if it were stopped at the locations described in the crash log and functions can
17831791
be disassembled and lookups can be performed using the addresses found in the crash log."""
1784-
return CreateSymbolicateCrashLogOptions("crashlog", description, True)
1792+
return CreateSymbolicateCrashLogOptions("crashlog", description)
17851793

17861794

17871795
def SymbolicateCrashLogs(debugger, command_args, result, is_command):
@@ -1797,8 +1805,35 @@ def SymbolicateCrashLogs(debugger, command_args, result, is_command):
17971805
result.SetError(str(e))
17981806
return
17991807

1808+
# To avoid breaking existing users, we should keep supporting legacy flags
1809+
# even if we don't use them / advertise them anymore.
1810+
if not options.mode:
1811+
if options.batch:
1812+
options.mode = CrashLogLoadingMode.batch
1813+
else:
1814+
options.mode = CrashLogLoadingMode.interactive
1815+
1816+
if options.mode != CrashLogLoadingMode.interactive and (
1817+
options.target_path or options.skip_status
1818+
):
1819+
print(
1820+
"Target path (-t) and skipping process status (-s) options can only used in interactive mode (-m=interactive)."
1821+
)
1822+
print("Aborting symbolication.")
1823+
arg_parser.print_help()
1824+
return
1825+
1826+
if options.version:
1827+
print(debugger.GetVersionString())
1828+
return
1829+
1830+
if options.debug:
1831+
print("command_args = %s" % command_args)
1832+
print("options", options)
1833+
print("args", options.reports)
1834+
18001835
# Interactive mode requires running the crashlog command from inside lldb.
1801-
if options.interactive and not is_command:
1836+
if options.mode == CrashLogLoadingMode.interactive and not is_command:
18021837
lldb_exec = (
18031838
subprocess.check_output(["/usr/bin/xcrun", "-f", "lldb"])
18041839
.decode("utf-8")
@@ -1824,31 +1859,26 @@ def SymbolicateCrashLogs(debugger, command_args, result, is_command):
18241859
print(debugger.GetVersionString())
18251860
return
18261861

1827-
if options.debug:
1828-
print("command_args = %s" % command_args)
1829-
print("options", options)
1830-
print("args", options.reports)
1831-
18321862
if options.debug_delay > 0:
18331863
print("Waiting %u seconds for debugger to attach..." % options.debug_delay)
18341864
time.sleep(options.debug_delay)
18351865
error = lldb.SBError()
18361866

18371867
def should_run_in_interactive_mode(options, ci):
1838-
if options.interactive:
1839-
return True
1840-
elif options.batch:
1868+
if options.mode == CrashLogLoadingMode.batch:
18411869
return False
1842-
# elif ci and ci.IsInteractive():
1843-
# return True
1870+
elif options.mode == CrashLogLoadingMode.interactive or (
1871+
ci and ci.IsInteractive()
1872+
):
1873+
return True
18441874
else:
1845-
return False
1875+
return sys.stdout.isatty()
18461876

18471877
ci = debugger.GetCommandInterpreter()
18481878

18491879
if options.reports:
18501880
for crashlog_file in options.reports:
1851-
crashlog_path = os.path.expanduser(crashlog_file)
1881+
crashlog_path = os.path.normpath(os.path.expanduser(crashlog_file))
18521882
if not os.path.exists(crashlog_path):
18531883
raise FileNotFoundError(
18541884
"crashlog file %s does not exist" % crashlog_path

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/altered_threadState.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# RUN: %clang_host -g %S/Inputs/test.c -o %t.out
22
# RUN: cp %S/Inputs/altered_threadState.crash %t.crash
33
# RUN: %python %S/patch-crashlog.py --binary %t.out --crashlog %t.crash --offsets '{"main":20, "bar":9, "foo":16}'
4-
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog %t.crash' 2>&1 | FileCheck %s
4+
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog -b %t.crash' 2>&1 | FileCheck %s
55

66
# CHECK: "crashlog" {{.*}} commands have been installed, use the "--help" options on these commands
77

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/json.test

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
# RUN: cp %S/Inputs/a.out.ips %t.crash
44
# RUN: %python %S/patch-crashlog.py --binary %t.out --crashlog %t.crash --offsets '{"main":20, "bar":9, "foo":16}' --json
5-
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog %t.crash' 2>&1 | FileCheck %s
6-
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog -c %t.crash' 2>&1 | FileCheck %s
5+
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog --mode batch %t.crash' 2>&1 | FileCheck %s
6+
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog --mode batch -c %t.crash' 2>&1 | FileCheck %s
77

88
# RUN: cp %S/Inputs/a.out.ips %t.nometadata.crash
99
# RUN: %python %S/patch-crashlog.py --binary %t.out --crashlog %t.nometadata.crash --offsets '{"main":20, "bar":9, "foo":16}' --json --no-metadata
10-
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog %t.nometadata.crash' 2>&1 | FileCheck %s
10+
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog --mode batch %t.nometadata.crash' 2>&1 | FileCheck %s
1111

1212
# CHECK: "crashlog" {{.*}} commands have been installed, use the "--help" options on these commands
1313

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/no_threadState.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# RUN: cp %S/Inputs/no_threadState.ips %t.crash
44
# RUN: %python %S/patch-crashlog.py --binary %t.out --crashlog %t.crash --offsets '{"main":20, "bar":9, "foo":16}' --json
5-
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog %t.crash' 2>&1 | FileCheck %s
5+
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog --mode batch %t.crash' 2>&1 | FileCheck %s
66

77
# CHECK: "crashlog" {{.*}} commands have been installed, use the "--help" options on these commands
88

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
# RUN: mkdir -p %t.dir
44
# RUN: yaml2obj %S/Inputs/interactive_crashlog/multithread-test.yaml > %t.dir/multithread-test
55
# RUN: %lldb -b -o 'command script import lldb.macosx.crashlog' \
6-
# RUN: -o 'crashlog -a -i -s -t %t.dir/multithread-test %S/Inputs/interactive_crashlog/multithread-test.ips' \
6+
# RUN: -o 'crashlog -a -s -t %t.dir/multithread-test %S/Inputs/interactive_crashlog/multithread-test.ips' \
77
# RUN: -o 'command source -s 0 %s' 2>&1 | FileCheck %s
88

99
# CHECK: "crashlog" {{.*}} commands have been installed, use the "--help" options on these commands

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/text.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# RUN: %clang_host -g %S/Inputs/test.c -o %t.out
22
# RUN: cp %S/Inputs/a.out.crash %t.crash
33
# RUN: %python %S/patch-crashlog.py --binary %t.out --crashlog %t.crash --offsets '{"main":20, "bar":9, "foo":16}'
4-
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog %t.crash' 2>&1 | FileCheck %s
4+
# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog -b %t.crash' 2>&1 | FileCheck %s
55

66
# CHECK: "crashlog" {{.*}} commands have been installed, use the "--help" options on these commands
77

0 commit comments

Comments
 (0)