blob: ef32bf09ce420f03434143d4c33518d60da30d89 [file] [log] [blame]
Elliott Hughes17de6ce2021-06-23 18:00:46 -07001#!/usr/bin/env python3
Josh Gao043bad72015-09-22 11:43:08 -07002#
3# Copyright (C) 2015 The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16#
17
18import adb
19import argparse
Alex Light92476652019-01-17 11:18:48 -080020import json
Josh Gao043bad72015-09-22 11:43:08 -070021import logging
22import os
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -070023import posixpath
Elliott Hughes89e1ecf2017-06-30 14:03:32 -070024import re
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -070025import shutil
Josh Gao043bad72015-09-22 11:43:08 -070026import subprocess
27import sys
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -070028import tempfile
Alex Light92476652019-01-17 11:18:48 -080029import textwrap
Josh Gao043bad72015-09-22 11:43:08 -070030
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +000031from typing import BinaryIO, Any
Nikita Putikhin516960e2023-05-31 21:57:38 +000032
Josh Gao043bad72015-09-22 11:43:08 -070033# Shared functions across gdbclient.py and ndk-gdb.py.
34import gdbrunner
35
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -070036g_temp_dirs = []
37
Haibo Huange194fce2020-01-06 14:40:27 -080038
Nikita Putikhin516960e2023-05-31 21:57:38 +000039def read_toolchain_config(root: str) -> str:
Pirama Arumuga Nainarf7f95442021-06-30 13:31:41 -070040 """Finds out current toolchain version."""
41 version_output = subprocess.check_output(
42 f'{root}/build/soong/scripts/get_clang_version.py',
43 text=True)
44 return version_output.strip()
Haibo Huange194fce2020-01-06 14:40:27 -080045
46
Nikita Putikhin516960e2023-05-31 21:57:38 +000047def get_lldb_path(toolchain_path: str) -> str | None:
Haibo Huange4d8bfd2020-07-22 16:37:35 -070048 for lldb_name in ['lldb.sh', 'lldb.cmd', 'lldb', 'lldb.exe']:
49 debugger_path = os.path.join(toolchain_path, "bin", lldb_name)
50 if os.path.isfile(debugger_path):
51 return debugger_path
52 return None
53
54
Nikita Putikhin516960e2023-05-31 21:57:38 +000055def get_lldb_server_path(root: str, clang_base: str, clang_version: str, arch: str) -> str:
Haibo Huange194fce2020-01-06 14:40:27 -080056 arch = {
57 'arm': 'arm',
58 'arm64': 'aarch64',
59 'x86': 'i386',
60 'x86_64': 'x86_64',
61 }[arch]
62 return os.path.join(root, clang_base, "linux-x86",
63 clang_version, "runtimes_ndk_cxx", arch, "lldb-server")
64
65
Nikita Putikhin516960e2023-05-31 21:57:38 +000066def get_tracer_pid(device: adb.AndroidDevice, pid: int | str | None) -> int:
Elliott Hughes89e1ecf2017-06-30 14:03:32 -070067 if pid is None:
68 return 0
69
70 line, _ = device.shell(["grep", "-e", "^TracerPid:", "/proc/{}/status".format(pid)])
71 tracer_pid = re.sub('TracerPid:\t(.*)\n', r'\1', line)
72 return int(tracer_pid)
73
74
Nikita Putikhin516960e2023-05-31 21:57:38 +000075def parse_args() -> argparse.Namespace:
Josh Gao043bad72015-09-22 11:43:08 -070076 parser = gdbrunner.ArgumentParser()
77
78 group = parser.add_argument_group(title="attach target")
79 group = group.add_mutually_exclusive_group(required=True)
80 group.add_argument(
81 "-p", dest="target_pid", metavar="PID", type=int,
82 help="attach to a process with specified PID")
83 group.add_argument(
84 "-n", dest="target_name", metavar="NAME",
85 help="attach to a process with specified name")
86 group.add_argument(
87 "-r", dest="run_cmd", metavar="CMD", nargs=argparse.REMAINDER,
88 help="run a binary on the device, with args")
89
90 parser.add_argument(
91 "--port", nargs="?", default="5039",
Elliott Hughes89e1ecf2017-06-30 14:03:32 -070092 help="override the port used on the host [default: 5039]")
Josh Gao043bad72015-09-22 11:43:08 -070093 parser.add_argument(
94 "--user", nargs="?", default="root",
95 help="user to run commands as on the device [default: root]")
Alex Light92476652019-01-17 11:18:48 -080096 parser.add_argument(
Alex Lighta8f224d2020-11-10 10:30:19 -080097 "--setup-forwarding", default=None,
Elliott Hughes4c8e8752021-06-25 14:23:22 -070098 choices=["lldb", "vscode-lldb"],
99 help=("Set up lldb-server and port forwarding. Prints commands or " +
Alex Light92476652019-01-17 11:18:48 -0800100 ".vscode/launch.json configuration needed to connect the debugging " +
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000101 "client to the server. 'vscode' with lldb and 'vscode-lldb' both " +
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700102 "require the 'vadimcn.vscode-lldb' extension."))
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000103 parser.add_argument(
104 "--vscode-launch-props", default=None,
105 dest="vscode_launch_props",
106 help=("JSON with extra properties to add to launch parameters when using " +
107 "vscode-lldb forwarding."))
Haibo Huange194fce2020-01-06 14:40:27 -0800108
Peter Collingbourne63bf1082018-12-19 20:51:42 -0800109 parser.add_argument(
110 "--env", nargs=1, action="append", metavar="VAR=VALUE",
111 help="set environment variable when running a binary")
Peter Collingbourneba548262022-03-03 12:17:43 -0800112 parser.add_argument(
113 "--chroot", nargs='?', default="", metavar="PATH",
114 help="run command in a chroot in the given directory")
Peter Collingbourne63bf1082018-12-19 20:51:42 -0800115
Josh Gao043bad72015-09-22 11:43:08 -0700116 return parser.parse_args()
117
118
Nikita Putikhin516960e2023-05-31 21:57:38 +0000119def verify_device(device: adb.AndroidDevice) -> None:
Junichi Uekawa6612c922020-09-07 11:20:59 +0900120 names = set([device.get_prop("ro.build.product"), device.get_prop("ro.product.name")])
Josh Gao466e2892017-07-13 15:39:05 -0700121 target_device = os.environ["TARGET_PRODUCT"]
Junichi Uekawa6612c922020-09-07 11:20:59 +0900122 if target_device not in names:
Josh Gao466e2892017-07-13 15:39:05 -0700123 msg = "TARGET_PRODUCT ({}) does not match attached device ({})"
Nikita Putikhin516960e2023-05-31 21:57:38 +0000124 sys.exit(msg.format(target_device, ", ".join(n if n else "None" for n in names)))
Josh Gao043bad72015-09-22 11:43:08 -0700125
126
Nikita Putikhin516960e2023-05-31 21:57:38 +0000127def get_remote_pid(device: adb.AndroidDevice, process_name: str) -> int:
Josh Gao043bad72015-09-22 11:43:08 -0700128 processes = gdbrunner.get_processes(device)
129 if process_name not in processes:
130 msg = "failed to find running process {}".format(process_name)
131 sys.exit(msg)
132 pids = processes[process_name]
133 if len(pids) > 1:
134 msg = "multiple processes match '{}': {}".format(process_name, pids)
135 sys.exit(msg)
136
137 # Fetch the binary using the PID later.
138 return pids[0]
139
140
Nikita Putikhin516960e2023-05-31 21:57:38 +0000141def make_temp_dir(prefix: str) -> str:
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700142 global g_temp_dirs
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700143 result = tempfile.mkdtemp(prefix='lldbclient-linker-')
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700144 g_temp_dirs.append(result)
145 return result
146
147
Nikita Putikhin516960e2023-05-31 21:57:38 +0000148def ensure_linker(device: adb.AndroidDevice, sysroot: str, interp: str | None) -> str | None:
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700149 """Ensure that the device's linker exists on the host.
150
151 PT_INTERP is usually /system/bin/linker[64], but on the device, that file is
152 a symlink to /apex/com.android.runtime/bin/linker[64]. The symbolized linker
153 binary on the host is located in ${sysroot}/apex, not in ${sysroot}/system,
154 so add the ${sysroot}/apex path to the solib search path.
155
156 PT_INTERP will be /system/bin/bootstrap/linker[64] for executables using the
157 non-APEX/bootstrap linker. No search path modification is needed.
158
159 For a tapas build, only an unbundled app is built, and there is no linker in
160 ${sysroot} at all, so copy the linker from the device.
161
162 Returns:
163 A directory to add to the soinfo search path or None if no directory
164 needs to be added.
165 """
166
167 # Static executables have no interpreter.
168 if interp is None:
169 return None
170
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700171 # lldb will search for the linker using the PT_INTERP path. First try to find
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700172 # it in the sysroot.
173 local_path = os.path.join(sysroot, interp.lstrip("/"))
174 if os.path.exists(local_path):
175 return None
176
177 # If the linker on the device is a symlink, search for the symlink's target
178 # in the sysroot directory.
179 interp_real, _ = device.shell(["realpath", interp])
180 interp_real = interp_real.strip()
181 local_path = os.path.join(sysroot, interp_real.lstrip("/"))
182 if os.path.exists(local_path):
183 if posixpath.basename(interp) == posixpath.basename(interp_real):
184 # Add the interpreter's directory to the search path.
185 return os.path.dirname(local_path)
186 else:
187 # If PT_INTERP is linker_asan[64], but the sysroot file is
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700188 # linker[64], then copy the local file to the name lldb expects.
189 result = make_temp_dir('lldbclient-linker-')
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700190 shutil.copy(local_path, os.path.join(result, posixpath.basename(interp)))
191 return result
192
193 # Pull the system linker.
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700194 result = make_temp_dir('lldbclient-linker-')
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700195 device.pull(interp, os.path.join(result, posixpath.basename(interp)))
196 return result
Josh Gao043bad72015-09-22 11:43:08 -0700197
198
Nikita Putikhin516960e2023-05-31 21:57:38 +0000199def handle_switches(args, sysroot: str) -> tuple[BinaryIO, int | None, str | None]:
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700200 """Fetch the targeted binary and determine how to attach lldb.
Josh Gao043bad72015-09-22 11:43:08 -0700201
202 Args:
203 args: Parsed arguments.
204 sysroot: Local sysroot path.
205
206 Returns:
207 (binary_file, attach_pid, run_cmd).
208 Precisely one of attach_pid or run_cmd will be None.
209 """
210
211 device = args.device
212 binary_file = None
213 pid = None
214 run_cmd = None
215
Josh Gao057c2732017-05-24 15:55:50 -0700216 args.su_cmd = ["su", args.user] if args.user else []
217
Josh Gao043bad72015-09-22 11:43:08 -0700218 if args.target_pid:
219 # Fetch the binary using the PID later.
220 pid = args.target_pid
221 elif args.target_name:
222 # Fetch the binary using the PID later.
223 pid = get_remote_pid(device, args.target_name)
224 elif args.run_cmd:
225 if not args.run_cmd[0]:
226 sys.exit("empty command passed to -r")
Josh Gao043bad72015-09-22 11:43:08 -0700227 run_cmd = args.run_cmd
Kevin Rocard258c89e2017-07-12 18:21:29 -0700228 if not run_cmd[0].startswith("/"):
229 try:
230 run_cmd[0] = gdbrunner.find_executable_path(device, args.run_cmd[0],
231 run_as_cmd=args.su_cmd)
232 except RuntimeError:
233 sys.exit("Could not find executable '{}' passed to -r, "
234 "please provide an absolute path.".format(args.run_cmd[0]))
235
David Pursell639d1c42015-10-20 15:38:32 -0700236 binary_file, local = gdbrunner.find_file(device, run_cmd[0], sysroot,
Josh Gao057c2732017-05-24 15:55:50 -0700237 run_as_cmd=args.su_cmd)
Josh Gao043bad72015-09-22 11:43:08 -0700238 if binary_file is None:
239 assert pid is not None
240 try:
David Pursell639d1c42015-10-20 15:38:32 -0700241 binary_file, local = gdbrunner.find_binary(device, pid, sysroot,
Josh Gao057c2732017-05-24 15:55:50 -0700242 run_as_cmd=args.su_cmd)
Josh Gao043bad72015-09-22 11:43:08 -0700243 except adb.ShellError:
244 sys.exit("failed to pull binary for PID {}".format(pid))
245
David Pursell639d1c42015-10-20 15:38:32 -0700246 if not local:
247 logging.warning("Couldn't find local unstripped executable in {},"
248 " symbols may not be available.".format(sysroot))
249
Josh Gao043bad72015-09-22 11:43:08 -0700250 return (binary_file, pid, run_cmd)
251
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000252def merge_launch_dict(base: dict[str, Any], to_add: dict[str, Any] | None) -> None:
253 """Merges two dicts describing VSCode launch.json properties: base and
254 to_add. Base is modified in-place with items from to_add.
255 Items from to_add that are not present in base are inserted. Items that are
256 present are merged following these rules:
257 - Lists are merged with to_add elements appended to the end of base
258 list. Only a list can be merged with a list.
259 - dicts are merged recursively. Only a dict can be merged with a dict.
260 - Other present values in base get overwritten with values from to_add.
261
262 The reason for these rules is that merging in new values should prefer to
263 expand the existing set instead of overwriting where possible.
264 """
265 if to_add is None:
266 return
267
268 for key, val in to_add.items():
269 if key not in base:
270 base[key] = val
271 else:
272 if isinstance(base[key], list) and not isinstance(val, list):
273 raise ValueError(f'Cannot merge non-list into list at key={key}. ' +
274 'You probably need to wrap your value into a list.')
275 if not isinstance(base[key], list) and isinstance(val, list):
276 raise ValueError(f'Cannot merge list into non-list at key={key}.')
277 if isinstance(base[key], dict) != isinstance(val, dict):
278 raise ValueError(f'Cannot merge dict and non-dict at key={key}')
279
280 # We don't allow the user to overwrite or interleave lists and don't allow
281 # to delete dict entries.
282 # It can be done but would make the implementation a bit more complicated
283 # and provides less value than adding elements.
284 # We expect that the config generated by gdbclient doesn't contain anything
285 # the user would want to remove.
286 if isinstance(base[key], list):
287 base[key] += val
288 elif isinstance(base[key], dict):
289 merge_launch_dict(base[key], val)
290 else:
291 base[key] = val
292
293
294def generate_vscode_lldb_script(root: str, sysroot: str, binary_name: str, port: str | int, solib_search_path: list[str], extra_props: dict[str, Any] | None) -> str:
Alex Lighta8f224d2020-11-10 10:30:19 -0800295 # TODO It would be nice if we didn't need to copy this or run the
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700296 # lldbclient.py program manually. Doing this would probably require
Alex Lighta8f224d2020-11-10 10:30:19 -0800297 # writing a vscode extension or modifying an existing one.
298 # TODO: https://code.visualstudio.com/api/references/vscode-api#debug and
299 # https://code.visualstudio.com/api/extension-guides/debugger-extension and
300 # https://github.com/vadimcn/vscode-lldb/blob/6b775c439992b6615e92f4938ee4e211f1b060cf/extension/pickProcess.ts#L6
301 res = {
302 "name": "(lldbclient.py) Attach {} (port: {})".format(binary_name.split("/")[-1], port),
303 "type": "lldb",
304 "request": "custom",
305 "relativePathBase": root,
306 "sourceMap": { "/b/f/w" : root, '': root, '.': root },
307 "initCommands": ['settings append target.exec-search-paths {}'.format(' '.join(solib_search_path))],
308 "targetCreateCommands": ["target create {}".format(binary_name),
309 "target modules search-paths add / {}/".format(sysroot)],
Peter Collingbourneb6b58a42023-03-15 14:11:00 -0700310 "processCreateCommands": ["gdb-remote {}".format(str(port))]
Alex Lighta8f224d2020-11-10 10:30:19 -0800311 }
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000312 merge_launch_dict(res, extra_props)
Alex Lighta8f224d2020-11-10 10:30:19 -0800313 return json.dumps(res, indent=4)
314
Nikita Putikhin516960e2023-05-31 21:57:38 +0000315def generate_lldb_script(root: str, sysroot: str, binary_name: str, port: str | int, solib_search_path: list[str]) -> str:
Haibo Huange194fce2020-01-06 14:40:27 -0800316 commands = []
317 commands.append(
318 'settings append target.exec-search-paths {}'.format(' '.join(solib_search_path)))
319
320 commands.append('target create {}'.format(binary_name))
Haibo Huang987436c2020-09-22 21:01:31 -0700321 # For RBE support.
322 commands.append("settings append target.source-map '/b/f/w' '{}'".format(root))
323 commands.append("settings append target.source-map '' '{}'".format(root))
Haibo Huange194fce2020-01-06 14:40:27 -0800324 commands.append('target modules search-paths add / {}/'.format(sysroot))
Peter Collingbourneb6b58a42023-03-15 14:11:00 -0700325 commands.append('gdb-remote {}'.format(str(port)))
Haibo Huange194fce2020-01-06 14:40:27 -0800326 return '\n'.join(commands)
327
328
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000329def generate_setup_script(sysroot: str, linker_search_dir: str | None, binary_name: str, is64bit: bool, port: str | int, debugger: str, vscode_launch_props: dict[str, Any] | None) -> str:
Alex Light92476652019-01-17 11:18:48 -0800330 # Generate a setup script.
Alex Light92476652019-01-17 11:18:48 -0800331 root = os.environ["ANDROID_BUILD_TOP"]
332 symbols_dir = os.path.join(sysroot, "system", "lib64" if is64bit else "lib")
333 vendor_dir = os.path.join(sysroot, "vendor", "lib64" if is64bit else "lib")
334
335 solib_search_path = []
336 symbols_paths = ["", "hw", "ssl/engines", "drm", "egl", "soundfx"]
337 vendor_paths = ["", "hw", "egl"]
338 solib_search_path += [os.path.join(symbols_dir, x) for x in symbols_paths]
339 solib_search_path += [os.path.join(vendor_dir, x) for x in vendor_paths]
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700340 if linker_search_dir is not None:
341 solib_search_path += [linker_search_dir]
Alex Light92476652019-01-17 11:18:48 -0800342
Alex Lighta8f224d2020-11-10 10:30:19 -0800343 if debugger == "vscode-lldb":
344 return generate_vscode_lldb_script(
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000345 root, sysroot, binary_name, port, solib_search_path, vscode_launch_props)
Haibo Huange194fce2020-01-06 14:40:27 -0800346 elif debugger == 'lldb':
347 return generate_lldb_script(
Nikita Putikhin516960e2023-05-31 21:57:38 +0000348 root, sysroot, binary_name, port, solib_search_path)
Alex Light92476652019-01-17 11:18:48 -0800349 else:
350 raise Exception("Unknown debugger type " + debugger)
351
Josh Gao043bad72015-09-22 11:43:08 -0700352
Nikita Putikhin516960e2023-05-31 21:57:38 +0000353def do_main() -> None:
Josh Gao466e2892017-07-13 15:39:05 -0700354 required_env = ["ANDROID_BUILD_TOP",
355 "ANDROID_PRODUCT_OUT", "TARGET_PRODUCT"]
356 for env in required_env:
357 if env not in os.environ:
358 sys.exit(
359 "Environment variable '{}' not defined, have you run lunch?".format(env))
360
Josh Gao043bad72015-09-22 11:43:08 -0700361 args = parse_args()
362 device = args.device
Josh Gao44b84a82015-10-28 11:57:37 -0700363
364 if device is None:
365 sys.exit("ERROR: Failed to find device.")
366
Josh Gao043bad72015-09-22 11:43:08 -0700367 root = os.environ["ANDROID_BUILD_TOP"]
Josh Gao466e2892017-07-13 15:39:05 -0700368 sysroot = os.path.join(os.environ["ANDROID_PRODUCT_OUT"], "symbols")
Josh Gao043bad72015-09-22 11:43:08 -0700369
370 # Make sure the environment matches the attached device.
Peter Collingbourneba548262022-03-03 12:17:43 -0800371 # Skip when running in a chroot because the chroot lunch target may not
372 # match the device's lunch target.
373 if not args.chroot:
Nikita Putikhin516960e2023-05-31 21:57:38 +0000374 verify_device(device)
Josh Gao043bad72015-09-22 11:43:08 -0700375
376 debug_socket = "/data/local/tmp/debug_socket"
377 pid = None
378 run_cmd = None
379
380 # Fetch binary for -p, -n.
David Pursell639d1c42015-10-20 15:38:32 -0700381 binary_file, pid, run_cmd = handle_switches(args, sysroot)
Josh Gao043bad72015-09-22 11:43:08 -0700382
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000383 vscode_launch_props = None
384 if args.vscode_launch_props:
385 if args.setup_forwarding != "vscode-lldb":
386 raise ValueError('vscode_launch_props requires --setup-forwarding=vscode-lldb')
387 vscode_launch_props = json.loads(args.vscode_launch_props)
388
Josh Gao043bad72015-09-22 11:43:08 -0700389 with binary_file:
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700390 if sys.platform.startswith("linux"):
391 platform_name = "linux-x86"
392 elif sys.platform.startswith("darwin"):
393 platform_name = "darwin-x86"
394 else:
395 sys.exit("Unknown platform: {}".format(sys.platform))
396
Josh Gao043bad72015-09-22 11:43:08 -0700397 arch = gdbrunner.get_binary_arch(binary_file)
398 is64bit = arch.endswith("64")
399
400 # Make sure we have the linker
Pirama Arumuga Nainarf7f95442021-06-30 13:31:41 -0700401 clang_base = 'prebuilts/clang/host'
402 clang_version = read_toolchain_config(root)
Haibo Huange194fce2020-01-06 14:40:27 -0800403 toolchain_path = os.path.join(root, clang_base, platform_name,
404 clang_version)
405 llvm_readobj_path = os.path.join(toolchain_path, "bin", "llvm-readobj")
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700406 interp = gdbrunner.get_binary_interp(binary_file.name, llvm_readobj_path)
407 linker_search_dir = ensure_linker(device, sysroot, interp)
Josh Gao043bad72015-09-22 11:43:08 -0700408
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700409 tracer_pid = get_tracer_pid(device, pid)
410 if tracer_pid == 0:
Peter Collingbourne63bf1082018-12-19 20:51:42 -0800411 cmd_prefix = args.su_cmd
412 if args.env:
413 cmd_prefix += ['env'] + [v[0] for v in args.env]
414
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700415 # Start lldb-server.
416 server_local_path = get_lldb_server_path(root, clang_base, clang_version, arch)
417 server_remote_path = "/data/local/tmp/{}-lldb-server".format(arch)
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700418 gdbrunner.start_gdbserver(
Haibo Huange194fce2020-01-06 14:40:27 -0800419 device, server_local_path, server_remote_path,
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700420 target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket,
Peter Collingbourneba548262022-03-03 12:17:43 -0800421 port=args.port, run_as_cmd=cmd_prefix, lldb=True, chroot=args.chroot)
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700422 else:
Haibo Huange194fce2020-01-06 14:40:27 -0800423 print(
424 "Connecting to tracing pid {} using local port {}".format(
425 tracer_pid, args.port))
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700426 gdbrunner.forward_gdbserver_port(device, local=args.port,
427 remote="tcp:{}".format(args.port))
Josh Gao043bad72015-09-22 11:43:08 -0700428
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700429 debugger_path = get_lldb_path(toolchain_path)
430 debugger = args.setup_forwarding or 'lldb'
Haibo Huange194fce2020-01-06 14:40:27 -0800431
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700432 # Generate the lldb script.
Nikita Putikhin516960e2023-05-31 21:57:38 +0000433 setup_commands = generate_setup_script(sysroot=sysroot,
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700434 linker_search_dir=linker_search_dir,
Nikita Putikhin516960e2023-05-31 21:57:38 +0000435 binary_name=binary_file.name,
Alex Light92476652019-01-17 11:18:48 -0800436 is64bit=is64bit,
437 port=args.port,
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000438 debugger=debugger,
439 vscode_launch_props=vscode_launch_props)
Josh Gao043bad72015-09-22 11:43:08 -0700440
Alex Lighta8f224d2020-11-10 10:30:19 -0800441 if not args.setup_forwarding:
Alex Light92476652019-01-17 11:18:48 -0800442 # Print a newline to separate our messages from the GDB session.
443 print("")
David Pursell639d1c42015-10-20 15:38:32 -0700444
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700445 # Start lldb.
446 gdbrunner.start_gdb(debugger_path, setup_commands, lldb=True)
Alex Light92476652019-01-17 11:18:48 -0800447 else:
448 print("")
Haibo Huange194fce2020-01-06 14:40:27 -0800449 print(setup_commands)
Alex Light92476652019-01-17 11:18:48 -0800450 print("")
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700451 if args.setup_forwarding == "vscode-lldb":
Haibo Huange194fce2020-01-06 14:40:27 -0800452 print(textwrap.dedent("""
Alex Light92476652019-01-17 11:18:48 -0800453 Paste the above json into .vscode/launch.json and start the debugger as
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700454 normal. Press enter in this terminal once debugging is finished to shut
455 lldb-server down and close all the ports."""))
Alex Light92476652019-01-17 11:18:48 -0800456 else:
Haibo Huange194fce2020-01-06 14:40:27 -0800457 print(textwrap.dedent("""
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700458 Paste the lldb commands above into the lldb frontend to set up the
459 lldb-server connection. Press enter in this terminal once debugging is
460 finished to shut lldb-server down and close all the ports."""))
Alex Light92476652019-01-17 11:18:48 -0800461 print("")
Siarhei Vishniakou9c4f1b32021-12-02 10:43:14 -0800462 input("Press enter to shut down lldb-server")
Josh Gao043bad72015-09-22 11:43:08 -0700463
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700464
465def main():
466 try:
467 do_main()
468 finally:
469 global g_temp_dirs
470 for temp_dir in g_temp_dirs:
471 shutil.rmtree(temp_dir)
472
473
Josh Gao043bad72015-09-22 11:43:08 -0700474if __name__ == "__main__":
475 main()