lldb-vscode

Add support for using lldb with vscode.

Test: lldbclient.py --setup-forwarding vscode -r dalvikvm
Bug: 176158605

Change-Id: I92a08b3b02a27a14be586582fe57acdd670a9ada
This commit is contained in:
Alex Light
2020-11-10 10:30:19 -08:00
parent 223d9273bb
commit a8f224d606

View File

@@ -112,10 +112,14 @@ def parse_args():
"--user", nargs="?", default="root",
help="user to run commands as on the device [default: root]")
parser.add_argument(
"--setup-forwarding", default=None, choices=["gdb", "vscode"],
help=("Setup the gdbserver and port forwarding. Prints commands or " +
"--setup-forwarding", default=None,
choices=["gdb", "lldb", "vscode", "vscode-gdb", "vscode-lldb"],
help=("Setup the gdbserver/lldb-server and port forwarding. Prints commands or " +
".vscode/launch.json configuration needed to connect the debugging " +
"client to the server."))
"client to the server. If 'gdb' and 'vscode-gdb' are only valid if " +
"'--no-lldb' is passed. 'vscode' with llbd and 'vscode-lldb' both " +
"require the 'vadimcn.vscode-lldb' extension. 'vscode' with '--no-lldb' " +
"and 'vscode-gdb' require the 'ms-vscode.cpptools' extension."))
lldb_group = parser.add_mutually_exclusive_group()
lldb_group.add_argument("--lldb", action="store_true", help="Use lldb.")
@@ -261,7 +265,27 @@ def handle_switches(args, sysroot):
return (binary_file, pid, run_cmd)
def generate_vscode_script(gdbpath, root, sysroot, binary_name, port, dalvik_gdb_script, solib_search_path):
def generate_vscode_lldb_script(root, sysroot, binary_name, port, solib_search_path):
# TODO It would be nice if we didn't need to copy this or run the
# gdbclient.py program manually. Doing this would probably require
# writing a vscode extension or modifying an existing one.
# TODO: https://code.visualstudio.com/api/references/vscode-api#debug and
# https://code.visualstudio.com/api/extension-guides/debugger-extension and
# https://github.com/vadimcn/vscode-lldb/blob/6b775c439992b6615e92f4938ee4e211f1b060cf/extension/pickProcess.ts#L6
res = {
"name": "(lldbclient.py) Attach {} (port: {})".format(binary_name.split("/")[-1], port),
"type": "lldb",
"request": "custom",
"relativePathBase": root,
"sourceMap": { "/b/f/w" : root, '': root, '.': root },
"initCommands": ['settings append target.exec-search-paths {}'.format(' '.join(solib_search_path))],
"targetCreateCommands": ["target create {}".format(binary_name),
"target modules search-paths add / {}/".format(sysroot)],
"processCreateCommands": ["gdb-remote {}".format(port)]
}
return json.dumps(res, indent=4)
def generate_vscode_gdb_script(gdbpath, root, sysroot, binary_name, port, dalvik_gdb_script, solib_search_path):
# TODO It would be nice if we didn't need to copy this or run the
# gdbclient.py program manually. Doing this would probably require
# writing a vscode extension or modifying an existing one.
@@ -380,9 +404,12 @@ def generate_setup_script(debugger_path, sysroot, linker_search_dir, binary_file
"be available").format(dalvik_gdb_script))
dalvik_gdb_script = None
if debugger == "vscode":
return generate_vscode_script(
if debugger == "vscode-gdb":
return generate_vscode_gdb_script(
debugger_path, root, sysroot, binary_file.name, port, dalvik_gdb_script, solib_search_path)
if debugger == "vscode-lldb":
return generate_vscode_lldb_script(
root, sysroot, binary_file.name, port, solib_search_path)
elif debugger == "gdb":
return generate_gdb_script(root, sysroot, binary_file.name, port, dalvik_gdb_script, solib_search_path, connect_timeout)
elif debugger == 'lldb':
@@ -406,6 +433,19 @@ def do_main():
if device is None:
sys.exit("ERROR: Failed to find device.")
use_lldb = not args.no_lldb
# Error check forwarding.
if args.setup_forwarding:
if use_lldb and (args.setup_forwarding == "gdb" or args.setup_forwarding == "vscode-gdb"):
sys.exit("Error: --setup-forwarding={} requires '--no-lldb'.".format(
args.setup_forwarding))
elif (not use_lldb) and (args.setup_forwarding == 'lldb' or args.setup_forwarding == 'vscode-lldb'):
sys.exit("Error: --setup-forwarding={} requires '--lldb'.".format(
args.setup_forwarding))
# Pick what vscode-debugger type to use.
if args.setup_forwarding == 'vscode':
args.setup_forwarding = 'vscode-lldb' if use_lldb else 'vscode-gdb'
root = os.environ["ANDROID_BUILD_TOP"]
sysroot = os.path.join(os.environ["ANDROID_PRODUCT_OUT"], "symbols")
@@ -442,7 +482,6 @@ def do_main():
if os.path.basename(__file__) == 'gdbclient.py' and not args.lldb:
print("gdb is deprecated in favor of lldb. "
"If you can't use lldb, please set --no-lldb and file a bug asap.")
use_lldb = not args.no_lldb
if tracer_pid == 0:
cmd_prefix = args.su_cmd
if args.env:
@@ -471,13 +510,13 @@ def do_main():
if use_lldb:
debugger_path = get_lldb_path(toolchain_path)
debugger = 'lldb'
debugger = args.setup_forwarding or 'lldb'
else:
debugger_path = os.path.join(
root, "prebuilts", "gdb", platform_name, "bin", "gdb")
debugger = args.setup_forwarding or "gdb"
# Generate a gdb script.
# Generate a gdb/lldb script.
setup_commands = generate_setup_script(debugger_path=debugger_path,
sysroot=sysroot,
linker_search_dir=linker_search_dir,
@@ -486,26 +525,27 @@ def do_main():
port=args.port,
debugger=debugger)
if use_lldb or not args.setup_forwarding:
if not args.setup_forwarding:
# Print a newline to separate our messages from the GDB session.
print("")
# Start gdb.
gdbrunner.start_gdb(debugger_path, setup_commands, lldb=use_lldb)
else:
debugger_name = "lldb" if use_lldb else "gdb"
print("")
print(setup_commands)
print("")
if args.setup_forwarding == "vscode":
if args.setup_forwarding == "vscode-{}".format(debugger_name):
print(textwrap.dedent("""
Paste the above json into .vscode/launch.json and start the debugger as
normal. Press enter in this terminal once debugging is finished to shutdown
the gdbserver and close all the ports."""))
else:
print(textwrap.dedent("""
Paste the above gdb commands into the gdb frontend to setup the gdbserver
connection. Press enter in this terminal once debugging is finished to
shutdown the gdbserver and close all the ports."""))
Paste the above {name} commands into the {name} frontend to setup the
gdbserver connection. Press enter in this terminal once debugging is
finished to shutdown the gdbserver and close all the ports.""".format(name=debugger_name)))
print("")
raw_input("Press enter to shutdown gdbserver")