Skip to content

Commit

Permalink
[lldb/crashlog] Replace deprecated optparse by argparse (NFC)
Browse files Browse the repository at this point in the history
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 <ismail@bennani.ma>
  • Loading branch information
medismailben committed Aug 18, 2023
1 parent 7602641 commit eef5ead
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 60 deletions.
128 changes: 70 additions & 58 deletions lldb/examples/python/crashlog.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
# ----------------------------------------------------------------------

import abc
import argparse
import concurrent.futures
import contextlib
import datetime
import json
import optparse
import os
import platform
import plistlib
Expand Down Expand Up @@ -1234,12 +1234,20 @@ def usage():


def save_crashlog(debugger, command, exe_ctx, result, dict):
usage = "usage: %prog [options] <output-path>"
usage = "save_crashlog [options] <output-path>"
description = """Export the state of current target into a crashlog file"""
parser = optparse.OptionParser(
description=description, prog="save_crashlog", usage=usage
parser = argparse.ArgumentParser(
description=description,
prog="save_crashlog",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
parser.add_option(
parser.add_argument(
"output",
metavar="output-file",
type=argparse.FileType("w", encoding="utf-8"),
nargs=1,
)
parser.add_argument(
"-v",
"--verbose",
action="store_true",
Expand All @@ -1248,21 +1256,13 @@ def save_crashlog(debugger, command, exe_ctx, result, dict):
default=False,
)
try:
(options, args) = parser.parse_args(shlex.split(command))
except:
result.PutCString("error: invalid options")
return
if len(args) != 1:
result.PutCString(
"error: invalid arguments, a single output file is the only valid argument"
)
return
out_file = open(args[0], "w", encoding="utf-8")
if not out_file:
result.PutCString("error: failed to open file '%s' for writing...", args[0])
options = parser.parse_args(shlex.split(command))
except Exception as e:
result.SetError(str(e))
return
target = exe_ctx.target
if target:
out_file = options.output
identifier = target.executable.basename
process = exe_ctx.process
if process:
Expand Down Expand Up @@ -1352,7 +1352,7 @@ def save_crashlog(debugger, command, exe_ctx, result, dict):
)
out_file.close()
else:
result.PutCString("error: invalid target")
result.SetError("invalid target")


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

def get_long_help(self):
option_parser = CrashLogOptionParser()
return option_parser.format_help()
arg_parser = CrashLogOptionParser()
return arg_parser.format_help()


def SymbolicateCrashLog(crash_log, options):
Expand Down Expand Up @@ -1523,35 +1523,46 @@ def synchronous(debugger):
def CreateSymbolicateCrashLogOptions(
command_name, description, add_interactive_options
):
usage = "usage: %prog [options] <FILE> [FILE ...]"
option_parser = optparse.OptionParser(
description=description, prog="crashlog", usage=usage
usage = "crashlog [options] <FILE> [FILE ...]"
arg_parser = argparse.ArgumentParser(
description=description,
prog="crashlog",
usage=usage,
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
arg_parser.add_argument(
"reports",
metavar="FILE",
type=str,
nargs="*",
help="crash report(s) to symbolicate",
)
option_parser.add_option(

arg_parser.add_argument(
"--version",
"-V",
dest="version",
action="store_true",
help="Show crashlog version",
default=False,
)
option_parser.add_option(
arg_parser.add_argument(
"--verbose",
"-v",
action="store_true",
dest="verbose",
help="display verbose debug info",
default=False,
)
option_parser.add_option(
arg_parser.add_argument(
"--debug",
"-g",
action="store_true",
dest="debug",
help="display verbose debug logging",
default=False,
)
option_parser.add_option(
arg_parser.add_argument(
"--load-all",
"-a",
action="store_true",
Expand All @@ -1561,116 +1572,116 @@ def CreateSymbolicateCrashLogOptions(
"interactive mode.",
default=False,
)
option_parser.add_option(
arg_parser.add_argument(
"--images",
action="store_true",
dest="dump_image_list",
help="show image list",
default=False,
)
option_parser.add_option(
arg_parser.add_argument(
"--debug-delay",
type="int",
type=int,
dest="debug_delay",
metavar="NSEC",
help="pause for NSEC seconds for debugger",
default=0,
)
option_parser.add_option(
arg_parser.add_argument(
"--crashed-only",
"-c",
action="store_true",
dest="crashed_only",
help="only symbolicate the crashed thread",
default=False,
)
option_parser.add_option(
arg_parser.add_argument(
"--disasm-depth",
"-d",
type="int",
type=int,
dest="disassemble_depth",
help="set the depth in stack frames that should be disassembled (default is 1)",
help="set the depth in stack frames that should be disassembled",
default=1,
)
option_parser.add_option(
arg_parser.add_argument(
"--disasm-all",
"-D",
action="store_true",
dest="disassemble_all_threads",
help="enabled disassembly of frames on all threads (not just the crashed thread)",
default=False,
)
option_parser.add_option(
arg_parser.add_argument(
"--disasm-before",
"-B",
type="int",
type=int,
dest="disassemble_before",
help="the number of instructions to disassemble before the frame PC",
default=4,
)
option_parser.add_option(
arg_parser.add_argument(
"--disasm-after",
"-A",
type="int",
type=int,
dest="disassemble_after",
help="the number of instructions to disassemble after the frame PC",
default=4,
)
option_parser.add_option(
arg_parser.add_argument(
"--source-context",
"-C",
type="int",
type=int,
metavar="NLINES",
dest="source_context",
help="show NLINES source lines of source context (default = 4)",
help="show NLINES source lines of source context",
default=4,
)
option_parser.add_option(
arg_parser.add_argument(
"--source-frames",
type="int",
type=int,
metavar="NFRAMES",
dest="source_frames",
help="show source for NFRAMES (default = 4)",
help="show source for NFRAMES",
default=4,
)
option_parser.add_option(
arg_parser.add_argument(
"--source-all",
action="store_true",
dest="source_all",
help="show source for all threads, not just the crashed thread",
default=False,
)
if add_interactive_options:
option_parser.add_option(
arg_parser.add_argument(
"-i",
"--interactive",
action="store_true",
help="parse a crash log and load it in a ScriptedProcess",
default=False,
)
option_parser.add_option(
arg_parser.add_argument(
"-b",
"--batch",
action="store_true",
help="dump symbolicated stackframes without creating a debug session",
default=True,
)
option_parser.add_option(
arg_parser.add_argument(
"--target",
"-t",
dest="target_path",
help="the target binary path that should be used for interactive crashlog (optional)",
default=None,
)
option_parser.add_option(
arg_parser.add_argument(
"--skip-status",
"-s",
dest="skip_status",
action="store_true",
help="prevent the interactive crashlog to dump the process status and thread backtrace at launch",
default=False,
)
return option_parser
return arg_parser


def CrashLogOptionParser():
Expand All @@ -1686,15 +1697,16 @@ def CrashLogOptionParser():


def SymbolicateCrashLogs(debugger, command_args, result, is_command):
option_parser = CrashLogOptionParser()
arg_parser = CrashLogOptionParser()

if not len(command_args):
option_parser.print_help()
arg_parser.print_help()
return

try:
(options, args) = option_parser.parse_args(command_args)
except:
options = arg_parser.parse_args(command_args)
except Exception as e:
result.SetError(str(e))
return

# Interactive mode requires running the crashlog command from inside lldb.
Expand Down Expand Up @@ -1724,7 +1736,7 @@ def SymbolicateCrashLogs(debugger, command_args, result, is_command):
if options.debug:
print("command_args = %s" % command_args)
print("options", options)
print("args", args)
print("args", options.reports)

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

ci = debugger.GetCommandInterpreter()

if args:
for crashlog_file in args:
if options.reports:
for crashlog_file in options.reports:
crashlog_path = os.path.expanduser(crashlog_file)
if not os.path.exists(crashlog_path):
raise FileNotFoundError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

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

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

0 comments on commit eef5ead

Please sign in to comment.