Skip to content

Commit eef5ead

Browse files
committed
[lldb/crashlog] Replace deprecated optparse by argparse (NFC)
This patch replace the deprecated `optparse` module used for the `crashlog`& `save_crashlog` commands with the new `argparse` from the python standard library. This provides many benefits such as showing the default values for each option in the help description, but also greatly improve the handling of position arguments. Differential Revision: https://reviews.llvm.org/D157849 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 7602641 commit eef5ead

File tree

2 files changed

+74
-60
lines changed

2 files changed

+74
-60
lines changed

lldb/examples/python/crashlog.py

Lines changed: 70 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@
2727
# ----------------------------------------------------------------------
2828

2929
import abc
30+
import argparse
3031
import concurrent.futures
3132
import contextlib
3233
import datetime
3334
import json
34-
import optparse
3535
import os
3636
import platform
3737
import plistlib
@@ -1234,12 +1234,20 @@ def usage():
12341234

12351235

12361236
def save_crashlog(debugger, command, exe_ctx, result, dict):
1237-
usage = "usage: %prog [options] <output-path>"
1237+
usage = "save_crashlog [options] <output-path>"
12381238
description = """Export the state of current target into a crashlog file"""
1239-
parser = optparse.OptionParser(
1240-
description=description, prog="save_crashlog", usage=usage
1239+
parser = argparse.ArgumentParser(
1240+
description=description,
1241+
prog="save_crashlog",
1242+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
12411243
)
1242-
parser.add_option(
1244+
parser.add_argument(
1245+
"output",
1246+
metavar="output-file",
1247+
type=argparse.FileType("w", encoding="utf-8"),
1248+
nargs=1,
1249+
)
1250+
parser.add_argument(
12431251
"-v",
12441252
"--verbose",
12451253
action="store_true",
@@ -1248,21 +1256,13 @@ def save_crashlog(debugger, command, exe_ctx, result, dict):
12481256
default=False,
12491257
)
12501258
try:
1251-
(options, args) = parser.parse_args(shlex.split(command))
1252-
except:
1253-
result.PutCString("error: invalid options")
1254-
return
1255-
if len(args) != 1:
1256-
result.PutCString(
1257-
"error: invalid arguments, a single output file is the only valid argument"
1258-
)
1259-
return
1260-
out_file = open(args[0], "w", encoding="utf-8")
1261-
if not out_file:
1262-
result.PutCString("error: failed to open file '%s' for writing...", args[0])
1259+
options = parser.parse_args(shlex.split(command))
1260+
except Exception as e:
1261+
result.SetError(str(e))
12631262
return
12641263
target = exe_ctx.target
12651264
if target:
1265+
out_file = options.output
12661266
identifier = target.executable.basename
12671267
process = exe_ctx.process
12681268
if process:
@@ -1352,7 +1352,7 @@ def save_crashlog(debugger, command, exe_ctx, result, dict):
13521352
)
13531353
out_file.close()
13541354
else:
1355-
result.PutCString("error: invalid target")
1355+
result.SetError("invalid target")
13561356

13571357

13581358
class Symbolicate:
@@ -1366,8 +1366,8 @@ def get_short_help(self):
13661366
return "Symbolicate one or more darwin crash log files."
13671367

13681368
def get_long_help(self):
1369-
option_parser = CrashLogOptionParser()
1370-
return option_parser.format_help()
1369+
arg_parser = CrashLogOptionParser()
1370+
return arg_parser.format_help()
13711371

13721372

13731373
def SymbolicateCrashLog(crash_log, options):
@@ -1523,35 +1523,46 @@ def synchronous(debugger):
15231523
def CreateSymbolicateCrashLogOptions(
15241524
command_name, description, add_interactive_options
15251525
):
1526-
usage = "usage: %prog [options] <FILE> [FILE ...]"
1527-
option_parser = optparse.OptionParser(
1528-
description=description, prog="crashlog", usage=usage
1526+
usage = "crashlog [options] <FILE> [FILE ...]"
1527+
arg_parser = argparse.ArgumentParser(
1528+
description=description,
1529+
prog="crashlog",
1530+
usage=usage,
1531+
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
1532+
)
1533+
arg_parser.add_argument(
1534+
"reports",
1535+
metavar="FILE",
1536+
type=str,
1537+
nargs="*",
1538+
help="crash report(s) to symbolicate",
15291539
)
1530-
option_parser.add_option(
1540+
1541+
arg_parser.add_argument(
15311542
"--version",
15321543
"-V",
15331544
dest="version",
15341545
action="store_true",
15351546
help="Show crashlog version",
15361547
default=False,
15371548
)
1538-
option_parser.add_option(
1549+
arg_parser.add_argument(
15391550
"--verbose",
15401551
"-v",
15411552
action="store_true",
15421553
dest="verbose",
15431554
help="display verbose debug info",
15441555
default=False,
15451556
)
1546-
option_parser.add_option(
1557+
arg_parser.add_argument(
15471558
"--debug",
15481559
"-g",
15491560
action="store_true",
15501561
dest="debug",
15511562
help="display verbose debug logging",
15521563
default=False,
15531564
)
1554-
option_parser.add_option(
1565+
arg_parser.add_argument(
15551566
"--load-all",
15561567
"-a",
15571568
action="store_true",
@@ -1561,116 +1572,116 @@ def CreateSymbolicateCrashLogOptions(
15611572
"interactive mode.",
15621573
default=False,
15631574
)
1564-
option_parser.add_option(
1575+
arg_parser.add_argument(
15651576
"--images",
15661577
action="store_true",
15671578
dest="dump_image_list",
15681579
help="show image list",
15691580
default=False,
15701581
)
1571-
option_parser.add_option(
1582+
arg_parser.add_argument(
15721583
"--debug-delay",
1573-
type="int",
1584+
type=int,
15741585
dest="debug_delay",
15751586
metavar="NSEC",
15761587
help="pause for NSEC seconds for debugger",
15771588
default=0,
15781589
)
1579-
option_parser.add_option(
1590+
arg_parser.add_argument(
15801591
"--crashed-only",
15811592
"-c",
15821593
action="store_true",
15831594
dest="crashed_only",
15841595
help="only symbolicate the crashed thread",
15851596
default=False,
15861597
)
1587-
option_parser.add_option(
1598+
arg_parser.add_argument(
15881599
"--disasm-depth",
15891600
"-d",
1590-
type="int",
1601+
type=int,
15911602
dest="disassemble_depth",
1592-
help="set the depth in stack frames that should be disassembled (default is 1)",
1603+
help="set the depth in stack frames that should be disassembled",
15931604
default=1,
15941605
)
1595-
option_parser.add_option(
1606+
arg_parser.add_argument(
15961607
"--disasm-all",
15971608
"-D",
15981609
action="store_true",
15991610
dest="disassemble_all_threads",
16001611
help="enabled disassembly of frames on all threads (not just the crashed thread)",
16011612
default=False,
16021613
)
1603-
option_parser.add_option(
1614+
arg_parser.add_argument(
16041615
"--disasm-before",
16051616
"-B",
1606-
type="int",
1617+
type=int,
16071618
dest="disassemble_before",
16081619
help="the number of instructions to disassemble before the frame PC",
16091620
default=4,
16101621
)
1611-
option_parser.add_option(
1622+
arg_parser.add_argument(
16121623
"--disasm-after",
16131624
"-A",
1614-
type="int",
1625+
type=int,
16151626
dest="disassemble_after",
16161627
help="the number of instructions to disassemble after the frame PC",
16171628
default=4,
16181629
)
1619-
option_parser.add_option(
1630+
arg_parser.add_argument(
16201631
"--source-context",
16211632
"-C",
1622-
type="int",
1633+
type=int,
16231634
metavar="NLINES",
16241635
dest="source_context",
1625-
help="show NLINES source lines of source context (default = 4)",
1636+
help="show NLINES source lines of source context",
16261637
default=4,
16271638
)
1628-
option_parser.add_option(
1639+
arg_parser.add_argument(
16291640
"--source-frames",
1630-
type="int",
1641+
type=int,
16311642
metavar="NFRAMES",
16321643
dest="source_frames",
1633-
help="show source for NFRAMES (default = 4)",
1644+
help="show source for NFRAMES",
16341645
default=4,
16351646
)
1636-
option_parser.add_option(
1647+
arg_parser.add_argument(
16371648
"--source-all",
16381649
action="store_true",
16391650
dest="source_all",
16401651
help="show source for all threads, not just the crashed thread",
16411652
default=False,
16421653
)
16431654
if add_interactive_options:
1644-
option_parser.add_option(
1655+
arg_parser.add_argument(
16451656
"-i",
16461657
"--interactive",
16471658
action="store_true",
16481659
help="parse a crash log and load it in a ScriptedProcess",
16491660
default=False,
16501661
)
1651-
option_parser.add_option(
1662+
arg_parser.add_argument(
16521663
"-b",
16531664
"--batch",
16541665
action="store_true",
16551666
help="dump symbolicated stackframes without creating a debug session",
16561667
default=True,
16571668
)
1658-
option_parser.add_option(
1669+
arg_parser.add_argument(
16591670
"--target",
16601671
"-t",
16611672
dest="target_path",
16621673
help="the target binary path that should be used for interactive crashlog (optional)",
16631674
default=None,
16641675
)
1665-
option_parser.add_option(
1676+
arg_parser.add_argument(
16661677
"--skip-status",
16671678
"-s",
16681679
dest="skip_status",
16691680
action="store_true",
16701681
help="prevent the interactive crashlog to dump the process status and thread backtrace at launch",
16711682
default=False,
16721683
)
1673-
return option_parser
1684+
return arg_parser
16741685

16751686

16761687
def CrashLogOptionParser():
@@ -1686,15 +1697,16 @@ def CrashLogOptionParser():
16861697

16871698

16881699
def SymbolicateCrashLogs(debugger, command_args, result, is_command):
1689-
option_parser = CrashLogOptionParser()
1700+
arg_parser = CrashLogOptionParser()
16901701

16911702
if not len(command_args):
1692-
option_parser.print_help()
1703+
arg_parser.print_help()
16931704
return
16941705

16951706
try:
1696-
(options, args) = option_parser.parse_args(command_args)
1697-
except:
1707+
options = arg_parser.parse_args(command_args)
1708+
except Exception as e:
1709+
result.SetError(str(e))
16981710
return
16991711

17001712
# Interactive mode requires running the crashlog command from inside lldb.
@@ -1724,7 +1736,7 @@ def SymbolicateCrashLogs(debugger, command_args, result, is_command):
17241736
if options.debug:
17251737
print("command_args = %s" % command_args)
17261738
print("options", options)
1727-
print("args", args)
1739+
print("args", options.reports)
17281740

17291741
if options.debug_delay > 0:
17301742
print("Waiting %u seconds for debugger to attach..." % options.debug_delay)
@@ -1743,8 +1755,8 @@ def should_run_in_interactive_mode(options, ci):
17431755

17441756
ci = debugger.GetCommandInterpreter()
17451757

1746-
if args:
1747-
for crashlog_file in args:
1758+
if options.reports:
1759+
for crashlog_file in options.reports:
17481760
crashlog_path = os.path.expanduser(crashlog_file)
17491761
if not os.path.exists(crashlog_path):
17501762
raise FileNotFoundError(

lldb/test/Shell/ScriptInterpreter/Python/Crashlog/no-args.test

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

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

5-
# CHECK: Usage: crashlog [options] <FILE> [FILE ...]
5+
# CHECK: usage: crashlog [options] <FILE> [FILE ...]
66
# CHECK: Symbolicate one or more darwin crash log files to provide source file and line
7-
# CHECK: Options:
7+
# CHECK: positional arguments:
8+
# CHECK-NEXT: FILE crash report(s) to symbolicate (default: None)
9+
# CHECK: options:
810
# CHECK: -h, --help show this help message and exit
911

0 commit comments

Comments
 (0)