Skip to content

Commit aafa0ef

Browse files
authored
[lldb/crashlog] Make interactive mode the new default (#94575)
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]>
1 parent d809152 commit aafa0ef

File tree

6 files changed

+83
-55
lines changed

6 files changed

+83
-55
lines changed

lldb/examples/python/crashlog.py

Lines changed: 76 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:
@@ -1582,9 +1582,12 @@ def synchronous(debugger):
15821582
debugger.RunCommandInterpreter(True, False, run_options, 0, False, True)
15831583

15841584

1585-
def CreateSymbolicateCrashLogOptions(
1586-
command_name, description, add_interactive_options
1587-
):
1585+
class CrashLogLoadingMode(str, enum.Enum):
1586+
batch = "batch"
1587+
interactive = "interactive"
1588+
1589+
1590+
def CreateSymbolicateCrashLogOptions(command_name, description):
15881591
usage = "crashlog [options] <FILE> [FILE ...]"
15891592
arg_parser = argparse.ArgumentParser(
15901593
description=description,
@@ -1600,6 +1603,12 @@ def CreateSymbolicateCrashLogOptions(
16001603
help="crash report(s) to symbolicate",
16011604
)
16021605

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

17711779

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

17831791

17841792
def SymbolicateCrashLogs(debugger, command_args, result, is_command):
@@ -1794,8 +1802,35 @@ def SymbolicateCrashLogs(debugger, command_args, result, is_command):
17941802
result.SetError(str(e))
17951803
return
17961804

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

1824-
if options.debug:
1825-
print("command_args = %s" % command_args)
1826-
print("options", options)
1827-
print("args", options.reports)
1828-
18291859
if options.debug_delay > 0:
18301860
print("Waiting %u seconds for debugger to attach..." % options.debug_delay)
18311861
time.sleep(options.debug_delay)
18321862
error = lldb.SBError()
18331863

18341864
def should_run_in_interactive_mode(options, ci):
1835-
if options.interactive:
1836-
return True
1837-
elif options.batch:
1865+
if options.mode == CrashLogLoadingMode.batch:
18381866
return False
1839-
# elif ci and ci.IsInteractive():
1840-
# return True
1867+
elif ci and ci.IsInteractive():
1868+
return True
18411869
else:
1842-
return False
1870+
return sys.stdout.isatty()
18431871

18441872
ci = debugger.GetCommandInterpreter()
18451873

18461874
if options.reports:
18471875
for crashlog_file in options.reports:
1848-
crashlog_path = os.path.expanduser(crashlog_file)
1876+
crashlog_path = os.path.normpath(os.path.expanduser(crashlog_file))
18491877
if not os.path.exists(crashlog_path):
18501878
raise FileNotFoundError(
18511879
"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)