Skip to content

Commit 02a02cb

Browse files
authored
Merge pull request swiftlang#8204 from jimingham/parsed-cmd-for-2030725
Add the new "parsed cmd" from llvm mainline to 2030725
2 parents 0937081 + afa76cb commit 02a02cb

File tree

20 files changed

+1863
-113
lines changed

20 files changed

+1863
-113
lines changed

lldb/bindings/python/CMakeLists.txt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -97,22 +97,24 @@ function(finish_swig_python swig_target lldb_python_bindings_dir lldb_python_tar
9797
${lldb_python_target_dir}
9898
"utils"
9999
FILES "${LLDB_SOURCE_DIR}/examples/python/in_call_stack.py"
100-
"${LLDB_SOURCE_DIR}/examples/python/symbolication.py")
100+
"${LLDB_SOURCE_DIR}/examples/python/symbolication.py"
101+
)
101102

102103
create_python_package(
103104
${swig_target}
104105
${lldb_python_target_dir}
105106
"plugins"
106107
FILES
107-
"${LLDB_SOURCE_DIR}/examples/python/scripted_process/scripted_process.py"
108-
"${LLDB_SOURCE_DIR}/examples/python/scripted_process/scripted_platform.py")
108+
"${LLDB_SOURCE_DIR}/examples/python/templates/parsed_cmd.py"
109+
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_process.py"
110+
"${LLDB_SOURCE_DIR}/examples/python/templates/scripted_platform.py")
109111

110112
if(APPLE)
111113
create_python_package(
112114
${swig_target}
113115
${lldb_python_target_dir} "macosx"
114116
FILES "${LLDB_SOURCE_DIR}/examples/python/crashlog.py"
115-
"${LLDB_SOURCE_DIR}/examples/python/scripted_process/crashlog_scripted_process.py"
117+
"${LLDB_SOURCE_DIR}/examples/python/crashlog_scripted_process.py"
116118
"${LLDB_SOURCE_DIR}/examples/darwin/heap_find/heap.py")
117119

118120
create_python_package(

lldb/bindings/python/python-wrapper.swig

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,12 +330,12 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedThrea
330330
}
331331

332332
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
333-
void *implementor, const char *method_name, lldb_private::Event *event,
333+
void *implementer, const char *method_name, lldb_private::Event *event,
334334
bool &got_error) {
335335
got_error = false;
336336

337337
PyErr_Cleaner py_err_cleaner(false);
338-
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
338+
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementer));
339339
auto pfunc = self.ResolveName<PythonCallable>(method_name);
340340

341341
if (!pfunc.IsAllocated())
@@ -368,12 +368,12 @@ bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
368368
}
369369

370370
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
371-
void *implementor, const char *method_name, lldb_private::Stream *stream,
371+
void *implementer, const char *method_name, lldb_private::Stream *stream,
372372
bool &got_error) {
373373
got_error = false;
374374

375375
PyErr_Cleaner py_err_cleaner(false);
376-
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
376+
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementer));
377377
auto pfunc = self.ResolveName<PythonCallable>(method_name);
378378

379379
if (!pfunc.IsAllocated())
@@ -874,6 +874,29 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommandObject(
874874
return true;
875875
}
876876

877+
#include "lldb/Interpreter/CommandReturnObject.h"
878+
879+
bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallParsedCommandObject(
880+
PyObject *implementor, lldb::DebuggerSP debugger, lldb_private::StructuredDataImpl &args_impl,
881+
lldb_private::CommandReturnObject &cmd_retobj,
882+
lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
883+
884+
PyErr_Cleaner py_err_cleaner(true);
885+
886+
PythonObject self(PyRefType::Borrowed, implementor);
887+
auto pfunc = self.ResolveName<PythonCallable>("__call__");
888+
889+
if (!pfunc.IsAllocated()) {
890+
cmd_retobj.AppendError("Could not find '__call__' method in implementation class");
891+
return false;
892+
}
893+
894+
pfunc(SWIGBridge::ToSWIGWrapper(std::move(debugger)), SWIGBridge::ToSWIGWrapper(args_impl),
895+
SWIGBridge::ToSWIGWrapper(exe_ctx_ref_sp), SWIGBridge::ToSWIGWrapper(cmd_retobj).obj());
896+
897+
return true;
898+
}
899+
877900
PythonObject lldb_private::python::SWIGBridge::LLDBSWIGPythonCreateOSPlugin(
878901
const char *python_class_name, const char *session_dictionary_name,
879902
const lldb::ProcessSP &process_sp) {

lldb/bindings/python/static-binding/LLDBWrapPython.cpp

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4968,12 +4968,12 @@ PythonObject lldb_private::python::SWIGBridge::LLDBSwigPythonCreateScriptedThrea
49684968
}
49694969

49704970
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
4971-
void *implementor, const char *method_name, lldb_private::Event *event,
4971+
void *implementer, const char *method_name, lldb_private::Event *event,
49724972
bool &got_error) {
49734973
got_error = false;
49744974

49754975
PyErr_Cleaner py_err_cleaner(false);
4976-
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
4976+
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementer));
49774977
auto pfunc = self.ResolveName<PythonCallable>(method_name);
49784978

49794979
if (!pfunc.IsAllocated())
@@ -5006,12 +5006,12 @@ bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
50065006
}
50075007

50085008
bool lldb_private::python::SWIGBridge::LLDBSWIGPythonCallThreadPlan(
5009-
void *implementor, const char *method_name, lldb_private::Stream *stream,
5009+
void *implementer, const char *method_name, lldb_private::Stream *stream,
50105010
bool &got_error) {
50115011
got_error = false;
50125012

50135013
PyErr_Cleaner py_err_cleaner(false);
5014-
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementor));
5014+
PythonObject self(PyRefType::Borrowed, static_cast<PyObject *>(implementer));
50155015
auto pfunc = self.ResolveName<PythonCallable>(method_name);
50165016

50175017
if (!pfunc.IsAllocated())
@@ -5512,6 +5512,29 @@ bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallCommandObject(
55125512
return true;
55135513
}
55145514

5515+
#include "lldb/Interpreter/CommandReturnObject.h"
5516+
5517+
bool lldb_private::python::SWIGBridge::LLDBSwigPythonCallParsedCommandObject(
5518+
PyObject *implementor, lldb::DebuggerSP debugger, lldb_private::StructuredDataImpl &args_impl,
5519+
lldb_private::CommandReturnObject &cmd_retobj,
5520+
lldb::ExecutionContextRefSP exe_ctx_ref_sp) {
5521+
5522+
PyErr_Cleaner py_err_cleaner(true);
5523+
5524+
PythonObject self(PyRefType::Borrowed, implementor);
5525+
auto pfunc = self.ResolveName<PythonCallable>("__call__");
5526+
5527+
if (!pfunc.IsAllocated()) {
5528+
cmd_retobj.AppendError("Could not find '__call__' method in implementation class");
5529+
return false;
5530+
}
5531+
5532+
pfunc(SWIGBridge::ToSWIGWrapper(std::move(debugger)), SWIGBridge::ToSWIGWrapper(args_impl),
5533+
SWIGBridge::ToSWIGWrapper(exe_ctx_ref_sp), SWIGBridge::ToSWIGWrapper(cmd_retobj).obj());
5534+
5535+
return true;
5536+
}
5537+
55155538
PythonObject lldb_private::python::SWIGBridge::LLDBSWIGPythonCreateOSPlugin(
55165539
const char *python_class_name, const char *session_dictionary_name,
55175540
const lldb::ProcessSP &process_sp) {

lldb/examples/python/cmdtemplate.py

Lines changed: 49 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -11,115 +11,84 @@
1111

1212
import inspect
1313
import lldb
14-
import optparse
15-
import shlex
1614
import sys
15+
from lldb.plugins.parsed_cmd import ParsedCommand
1716

18-
19-
class FrameStatCommand:
17+
class FrameStatCommand(ParsedCommand):
2018
program = "framestats"
2119

2220
@classmethod
2321
def register_lldb_command(cls, debugger, module_name):
24-
parser = cls.create_options()
25-
cls.__doc__ = parser.format_help()
26-
# Add any commands contained in this module to LLDB
27-
command = "command script add -o -c %s.%s %s" % (
28-
module_name,
29-
cls.__name__,
30-
cls.program,
31-
)
32-
debugger.HandleCommand(command)
22+
ParsedCommandBase.do_register_cmd(cls, debugger, module_name)
3323
print(
3424
'The "{0}" command has been installed, type "help {0}" or "{0} '
3525
'--help" for detailed help.'.format(cls.program)
3626
)
3727

38-
@classmethod
39-
def create_options(cls):
40-
usage = "usage: %prog [options]"
41-
description = (
42-
"This command is meant to be an example of how to make "
43-
"an LLDB command that does something useful, follows "
44-
"best practices, and exploits the SB API. "
45-
"Specifically, this command computes the aggregate "
46-
"and average size of the variables in the current "
47-
"frame and allows you to tweak exactly which variables "
48-
"are to be accounted in the computation."
49-
)
28+
def setup_command_definition(self):
5029

51-
# Pass add_help_option = False, since this keeps the command in line
52-
# with lldb commands, and we wire up "help command" to work by
53-
# providing the long & short help methods below.
54-
parser = optparse.OptionParser(
55-
description=description,
56-
prog=cls.program,
57-
usage=usage,
58-
add_help_option=False,
30+
self.ov_parser.add_option(
31+
"i",
32+
"in-scope",
33+
help = "in_scope_only = True",
34+
value_type = lldb.eArgTypeBoolean,
35+
dest = "bool_arg",
36+
default = True,
5937
)
6038

61-
parser.add_option(
62-
"-i",
63-
"--in-scope",
64-
action="store_true",
65-
dest="inscope",
66-
help="in_scope_only = True",
39+
self.ov_parser.add_option(
40+
"i",
41+
"in-scope",
42+
help = "in_scope_only = True",
43+
value_type = lldb.eArgTypeBoolean,
44+
dest = "inscope",
6745
default=True,
6846
)
69-
70-
parser.add_option(
71-
"-a",
72-
"--arguments",
73-
action="store_true",
74-
dest="arguments",
75-
help="arguments = True",
76-
default=True,
47+
48+
self.ov_parser.add_option(
49+
"a",
50+
"arguments",
51+
help = "arguments = True",
52+
value_type = lldb.eArgTypeBoolean,
53+
dest = "arguments",
54+
default = True,
7755
)
7856

79-
parser.add_option(
80-
"-l",
81-
"--locals",
82-
action="store_true",
83-
dest="locals",
84-
help="locals = True",
85-
default=True,
57+
self.ov_parser.add_option(
58+
"l",
59+
"locals",
60+
help = "locals = True",
61+
value_type = lldb.eArgTypeBoolean,
62+
dest = "locals",
63+
default = True,
8664
)
8765

88-
parser.add_option(
89-
"-s",
90-
"--statics",
91-
action="store_true",
92-
dest="statics",
93-
help="statics = True",
94-
default=True,
66+
self.ov_parser.add_option(
67+
"s",
68+
"statics",
69+
help = "statics = True",
70+
value_type = lldb.eArgTypeBoolean,
71+
dest = "statics",
72+
default = True,
9573
)
9674

97-
return parser
98-
9975
def get_short_help(self):
10076
return "Example command for use in debugging"
10177

10278
def get_long_help(self):
103-
return self.help_string
79+
return ("This command is meant to be an example of how to make "
80+
"an LLDB command that does something useful, follows "
81+
"best practices, and exploits the SB API. "
82+
"Specifically, this command computes the aggregate "
83+
"and average size of the variables in the current "
84+
"frame and allows you to tweak exactly which variables "
85+
"are to be accounted in the computation.")
86+
10487

10588
def __init__(self, debugger, unused):
106-
self.parser = self.create_options()
107-
self.help_string = self.parser.format_help()
89+
super().__init__(debugger, unused)
10890

10991
def __call__(self, debugger, command, exe_ctx, result):
110-
# Use the Shell Lexer to properly parse up command options just like a
111-
# shell would
112-
command_args = shlex.split(command)
113-
114-
try:
115-
(options, args) = self.parser.parse_args(command_args)
116-
except:
117-
# if you don't handle exceptions, passing an incorrect argument to
118-
# the OptionParser will cause LLDB to exit (courtesy of OptParse
119-
# dealing with argument errors by throwing SystemExit)
120-
result.SetError("option parsing failed")
121-
return
122-
12392
# Always get program state from the lldb.SBExecutionContext passed
12493
# in as exe_ctx
12594
frame = exe_ctx.GetFrame()
@@ -128,7 +97,7 @@ def __call__(self, debugger, command, exe_ctx, result):
12897
return
12998

13099
variables_list = frame.GetVariables(
131-
options.arguments, options.locals, options.statics, options.inscope
100+
self.ov_parser.arguments, self.ov_parser.locals, self.ov_parser.statics, self.ov_parser.inscope
132101
)
133102
variables_count = variables_list.GetSize()
134103
if variables_count == 0:

0 commit comments

Comments
 (0)