blob: b053a489de004e051dc0ac0f39be4f61b9adb609 [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',
Samuel Hollandc434dec2023-06-16 09:35:40 -070059 'riscv64': 'riscv64',
Haibo Huange194fce2020-01-06 14:40:27 -080060 'x86': 'i386',
61 'x86_64': 'x86_64',
62 }[arch]
63 return os.path.join(root, clang_base, "linux-x86",
64 clang_version, "runtimes_ndk_cxx", arch, "lldb-server")
65
66
Nikita Putikhin516960e2023-05-31 21:57:38 +000067def get_tracer_pid(device: adb.AndroidDevice, pid: int | str | None) -> int:
Elliott Hughes89e1ecf2017-06-30 14:03:32 -070068 if pid is None:
69 return 0
70
71 line, _ = device.shell(["grep", "-e", "^TracerPid:", "/proc/{}/status".format(pid)])
72 tracer_pid = re.sub('TracerPid:\t(.*)\n', r'\1', line)
73 return int(tracer_pid)
74
75
Nikita Putikhin516960e2023-05-31 21:57:38 +000076def parse_args() -> argparse.Namespace:
Josh Gao043bad72015-09-22 11:43:08 -070077 parser = gdbrunner.ArgumentParser()
78
79 group = parser.add_argument_group(title="attach target")
80 group = group.add_mutually_exclusive_group(required=True)
81 group.add_argument(
82 "-p", dest="target_pid", metavar="PID", type=int,
83 help="attach to a process with specified PID")
84 group.add_argument(
85 "-n", dest="target_name", metavar="NAME",
86 help="attach to a process with specified name")
87 group.add_argument(
88 "-r", dest="run_cmd", metavar="CMD", nargs=argparse.REMAINDER,
89 help="run a binary on the device, with args")
90
91 parser.add_argument(
92 "--port", nargs="?", default="5039",
Elliott Hughes89e1ecf2017-06-30 14:03:32 -070093 help="override the port used on the host [default: 5039]")
Josh Gao043bad72015-09-22 11:43:08 -070094 parser.add_argument(
95 "--user", nargs="?", default="root",
96 help="user to run commands as on the device [default: root]")
Alex Light92476652019-01-17 11:18:48 -080097 parser.add_argument(
Alex Lighta8f224d2020-11-10 10:30:19 -080098 "--setup-forwarding", default=None,
Elliott Hughes4c8e8752021-06-25 14:23:22 -070099 choices=["lldb", "vscode-lldb"],
100 help=("Set up lldb-server and port forwarding. Prints commands or " +
Alex Light92476652019-01-17 11:18:48 -0800101 ".vscode/launch.json configuration needed to connect the debugging " +
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000102 "client to the server. 'vscode' with lldb and 'vscode-lldb' both " +
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700103 "require the 'vadimcn.vscode-lldb' extension."))
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000104 parser.add_argument(
105 "--vscode-launch-props", default=None,
106 dest="vscode_launch_props",
107 help=("JSON with extra properties to add to launch parameters when using " +
108 "vscode-lldb forwarding."))
Haibo Huange194fce2020-01-06 14:40:27 -0800109
Peter Collingbourne63bf1082018-12-19 20:51:42 -0800110 parser.add_argument(
111 "--env", nargs=1, action="append", metavar="VAR=VALUE",
112 help="set environment variable when running a binary")
Peter Collingbourneba548262022-03-03 12:17:43 -0800113 parser.add_argument(
114 "--chroot", nargs='?', default="", metavar="PATH",
115 help="run command in a chroot in the given directory")
Peter Collingbourne63bf1082018-12-19 20:51:42 -0800116
Josh Gao043bad72015-09-22 11:43:08 -0700117 return parser.parse_args()
118
119
Nikita Putikhin516960e2023-05-31 21:57:38 +0000120def verify_device(device: adb.AndroidDevice) -> None:
Junichi Uekawa6612c922020-09-07 11:20:59 +0900121 names = set([device.get_prop("ro.build.product"), device.get_prop("ro.product.name")])
Josh Gao466e2892017-07-13 15:39:05 -0700122 target_device = os.environ["TARGET_PRODUCT"]
Junichi Uekawa6612c922020-09-07 11:20:59 +0900123 if target_device not in names:
Josh Gao466e2892017-07-13 15:39:05 -0700124 msg = "TARGET_PRODUCT ({}) does not match attached device ({})"
Nikita Putikhin516960e2023-05-31 21:57:38 +0000125 sys.exit(msg.format(target_device, ", ".join(n if n else "None" for n in names)))
Josh Gao043bad72015-09-22 11:43:08 -0700126
127
Nikita Putikhin516960e2023-05-31 21:57:38 +0000128def get_remote_pid(device: adb.AndroidDevice, process_name: str) -> int:
Josh Gao043bad72015-09-22 11:43:08 -0700129 processes = gdbrunner.get_processes(device)
130 if process_name not in processes:
131 msg = "failed to find running process {}".format(process_name)
132 sys.exit(msg)
133 pids = processes[process_name]
134 if len(pids) > 1:
135 msg = "multiple processes match '{}': {}".format(process_name, pids)
136 sys.exit(msg)
137
138 # Fetch the binary using the PID later.
139 return pids[0]
140
141
Nikita Putikhin516960e2023-05-31 21:57:38 +0000142def make_temp_dir(prefix: str) -> str:
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700143 global g_temp_dirs
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700144 result = tempfile.mkdtemp(prefix='lldbclient-linker-')
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700145 g_temp_dirs.append(result)
146 return result
147
148
Nikita Putikhin516960e2023-05-31 21:57:38 +0000149def ensure_linker(device: adb.AndroidDevice, sysroot: str, interp: str | None) -> str | None:
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700150 """Ensure that the device's linker exists on the host.
151
152 PT_INTERP is usually /system/bin/linker[64], but on the device, that file is
153 a symlink to /apex/com.android.runtime/bin/linker[64]. The symbolized linker
154 binary on the host is located in ${sysroot}/apex, not in ${sysroot}/system,
155 so add the ${sysroot}/apex path to the solib search path.
156
157 PT_INTERP will be /system/bin/bootstrap/linker[64] for executables using the
158 non-APEX/bootstrap linker. No search path modification is needed.
159
160 For a tapas build, only an unbundled app is built, and there is no linker in
161 ${sysroot} at all, so copy the linker from the device.
162
163 Returns:
164 A directory to add to the soinfo search path or None if no directory
165 needs to be added.
166 """
167
168 # Static executables have no interpreter.
169 if interp is None:
170 return None
171
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700172 # lldb will search for the linker using the PT_INTERP path. First try to find
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700173 # it in the sysroot.
174 local_path = os.path.join(sysroot, interp.lstrip("/"))
175 if os.path.exists(local_path):
176 return None
177
178 # If the linker on the device is a symlink, search for the symlink's target
179 # in the sysroot directory.
180 interp_real, _ = device.shell(["realpath", interp])
181 interp_real = interp_real.strip()
182 local_path = os.path.join(sysroot, interp_real.lstrip("/"))
183 if os.path.exists(local_path):
184 if posixpath.basename(interp) == posixpath.basename(interp_real):
185 # Add the interpreter's directory to the search path.
186 return os.path.dirname(local_path)
187 else:
188 # If PT_INTERP is linker_asan[64], but the sysroot file is
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700189 # linker[64], then copy the local file to the name lldb expects.
190 result = make_temp_dir('lldbclient-linker-')
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700191 shutil.copy(local_path, os.path.join(result, posixpath.basename(interp)))
192 return result
193
194 # Pull the system linker.
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700195 result = make_temp_dir('lldbclient-linker-')
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700196 device.pull(interp, os.path.join(result, posixpath.basename(interp)))
197 return result
Josh Gao043bad72015-09-22 11:43:08 -0700198
199
Nikita Putikhin516960e2023-05-31 21:57:38 +0000200def handle_switches(args, sysroot: str) -> tuple[BinaryIO, int | None, str | None]:
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700201 """Fetch the targeted binary and determine how to attach lldb.
Josh Gao043bad72015-09-22 11:43:08 -0700202
203 Args:
204 args: Parsed arguments.
205 sysroot: Local sysroot path.
206
207 Returns:
208 (binary_file, attach_pid, run_cmd).
209 Precisely one of attach_pid or run_cmd will be None.
210 """
211
212 device = args.device
213 binary_file = None
214 pid = None
215 run_cmd = None
216
Josh Gao057c2732017-05-24 15:55:50 -0700217 args.su_cmd = ["su", args.user] if args.user else []
218
Josh Gao043bad72015-09-22 11:43:08 -0700219 if args.target_pid:
220 # Fetch the binary using the PID later.
221 pid = args.target_pid
222 elif args.target_name:
223 # Fetch the binary using the PID later.
224 pid = get_remote_pid(device, args.target_name)
225 elif args.run_cmd:
226 if not args.run_cmd[0]:
227 sys.exit("empty command passed to -r")
Josh Gao043bad72015-09-22 11:43:08 -0700228 run_cmd = args.run_cmd
Kevin Rocard258c89e2017-07-12 18:21:29 -0700229 if not run_cmd[0].startswith("/"):
230 try:
231 run_cmd[0] = gdbrunner.find_executable_path(device, args.run_cmd[0],
232 run_as_cmd=args.su_cmd)
233 except RuntimeError:
234 sys.exit("Could not find executable '{}' passed to -r, "
235 "please provide an absolute path.".format(args.run_cmd[0]))
236
David Pursell639d1c42015-10-20 15:38:32 -0700237 binary_file, local = gdbrunner.find_file(device, run_cmd[0], sysroot,
Josh Gao057c2732017-05-24 15:55:50 -0700238 run_as_cmd=args.su_cmd)
Josh Gao043bad72015-09-22 11:43:08 -0700239 if binary_file is None:
240 assert pid is not None
241 try:
David Pursell639d1c42015-10-20 15:38:32 -0700242 binary_file, local = gdbrunner.find_binary(device, pid, sysroot,
Josh Gao057c2732017-05-24 15:55:50 -0700243 run_as_cmd=args.su_cmd)
Josh Gao043bad72015-09-22 11:43:08 -0700244 except adb.ShellError:
245 sys.exit("failed to pull binary for PID {}".format(pid))
246
David Pursell639d1c42015-10-20 15:38:32 -0700247 if not local:
248 logging.warning("Couldn't find local unstripped executable in {},"
249 " symbols may not be available.".format(sysroot))
250
Josh Gao043bad72015-09-22 11:43:08 -0700251 return (binary_file, pid, run_cmd)
252
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000253def merge_launch_dict(base: dict[str, Any], to_add: dict[str, Any] | None) -> None:
254 """Merges two dicts describing VSCode launch.json properties: base and
255 to_add. Base is modified in-place with items from to_add.
256 Items from to_add that are not present in base are inserted. Items that are
257 present are merged following these rules:
258 - Lists are merged with to_add elements appended to the end of base
259 list. Only a list can be merged with a list.
260 - dicts are merged recursively. Only a dict can be merged with a dict.
261 - Other present values in base get overwritten with values from to_add.
262
263 The reason for these rules is that merging in new values should prefer to
264 expand the existing set instead of overwriting where possible.
265 """
266 if to_add is None:
267 return
268
269 for key, val in to_add.items():
270 if key not in base:
271 base[key] = val
272 else:
273 if isinstance(base[key], list) and not isinstance(val, list):
274 raise ValueError(f'Cannot merge non-list into list at key={key}. ' +
275 'You probably need to wrap your value into a list.')
276 if not isinstance(base[key], list) and isinstance(val, list):
277 raise ValueError(f'Cannot merge list into non-list at key={key}.')
278 if isinstance(base[key], dict) != isinstance(val, dict):
279 raise ValueError(f'Cannot merge dict and non-dict at key={key}')
280
281 # We don't allow the user to overwrite or interleave lists and don't allow
282 # to delete dict entries.
283 # It can be done but would make the implementation a bit more complicated
284 # and provides less value than adding elements.
285 # We expect that the config generated by gdbclient doesn't contain anything
286 # the user would want to remove.
287 if isinstance(base[key], list):
288 base[key] += val
289 elif isinstance(base[key], dict):
290 merge_launch_dict(base[key], val)
291 else:
292 base[key] = val
293
294
295def 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 -0800296 # TODO It would be nice if we didn't need to copy this or run the
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700297 # lldbclient.py program manually. Doing this would probably require
Alex Lighta8f224d2020-11-10 10:30:19 -0800298 # writing a vscode extension or modifying an existing one.
299 # TODO: https://code.visualstudio.com/api/references/vscode-api#debug and
300 # https://code.visualstudio.com/api/extension-guides/debugger-extension and
301 # https://github.com/vadimcn/vscode-lldb/blob/6b775c439992b6615e92f4938ee4e211f1b060cf/extension/pickProcess.ts#L6
302 res = {
303 "name": "(lldbclient.py) Attach {} (port: {})".format(binary_name.split("/")[-1], port),
304 "type": "lldb",
305 "request": "custom",
306 "relativePathBase": root,
307 "sourceMap": { "/b/f/w" : root, '': root, '.': root },
308 "initCommands": ['settings append target.exec-search-paths {}'.format(' '.join(solib_search_path))],
309 "targetCreateCommands": ["target create {}".format(binary_name),
310 "target modules search-paths add / {}/".format(sysroot)],
Peter Collingbourneb6b58a42023-03-15 14:11:00 -0700311 "processCreateCommands": ["gdb-remote {}".format(str(port))]
Alex Lighta8f224d2020-11-10 10:30:19 -0800312 }
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000313 merge_launch_dict(res, extra_props)
Alex Lighta8f224d2020-11-10 10:30:19 -0800314 return json.dumps(res, indent=4)
315
Nikita Putikhin516960e2023-05-31 21:57:38 +0000316def 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 -0800317 commands = []
318 commands.append(
319 'settings append target.exec-search-paths {}'.format(' '.join(solib_search_path)))
320
321 commands.append('target create {}'.format(binary_name))
Haibo Huang987436c2020-09-22 21:01:31 -0700322 # For RBE support.
323 commands.append("settings append target.source-map '/b/f/w' '{}'".format(root))
324 commands.append("settings append target.source-map '' '{}'".format(root))
Haibo Huange194fce2020-01-06 14:40:27 -0800325 commands.append('target modules search-paths add / {}/'.format(sysroot))
Peter Collingbourneb6b58a42023-03-15 14:11:00 -0700326 commands.append('gdb-remote {}'.format(str(port)))
Haibo Huange194fce2020-01-06 14:40:27 -0800327 return '\n'.join(commands)
328
329
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000330def 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 -0800331 # Generate a setup script.
Alex Light92476652019-01-17 11:18:48 -0800332 root = os.environ["ANDROID_BUILD_TOP"]
333 symbols_dir = os.path.join(sysroot, "system", "lib64" if is64bit else "lib")
334 vendor_dir = os.path.join(sysroot, "vendor", "lib64" if is64bit else "lib")
335
336 solib_search_path = []
337 symbols_paths = ["", "hw", "ssl/engines", "drm", "egl", "soundfx"]
338 vendor_paths = ["", "hw", "egl"]
339 solib_search_path += [os.path.join(symbols_dir, x) for x in symbols_paths]
340 solib_search_path += [os.path.join(vendor_dir, x) for x in vendor_paths]
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700341 if linker_search_dir is not None:
342 solib_search_path += [linker_search_dir]
Alex Light92476652019-01-17 11:18:48 -0800343
Alex Lighta8f224d2020-11-10 10:30:19 -0800344 if debugger == "vscode-lldb":
345 return generate_vscode_lldb_script(
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000346 root, sysroot, binary_name, port, solib_search_path, vscode_launch_props)
Haibo Huange194fce2020-01-06 14:40:27 -0800347 elif debugger == 'lldb':
348 return generate_lldb_script(
Nikita Putikhin516960e2023-05-31 21:57:38 +0000349 root, sysroot, binary_name, port, solib_search_path)
Alex Light92476652019-01-17 11:18:48 -0800350 else:
351 raise Exception("Unknown debugger type " + debugger)
352
Josh Gao043bad72015-09-22 11:43:08 -0700353
Nikita Putikhin516960e2023-05-31 21:57:38 +0000354def do_main() -> None:
Josh Gao466e2892017-07-13 15:39:05 -0700355 required_env = ["ANDROID_BUILD_TOP",
356 "ANDROID_PRODUCT_OUT", "TARGET_PRODUCT"]
357 for env in required_env:
358 if env not in os.environ:
359 sys.exit(
360 "Environment variable '{}' not defined, have you run lunch?".format(env))
361
Josh Gao043bad72015-09-22 11:43:08 -0700362 args = parse_args()
363 device = args.device
Josh Gao44b84a82015-10-28 11:57:37 -0700364
365 if device is None:
366 sys.exit("ERROR: Failed to find device.")
367
Josh Gao043bad72015-09-22 11:43:08 -0700368 root = os.environ["ANDROID_BUILD_TOP"]
Josh Gao466e2892017-07-13 15:39:05 -0700369 sysroot = os.path.join(os.environ["ANDROID_PRODUCT_OUT"], "symbols")
Josh Gao043bad72015-09-22 11:43:08 -0700370
371 # Make sure the environment matches the attached device.
Peter Collingbourneba548262022-03-03 12:17:43 -0800372 # Skip when running in a chroot because the chroot lunch target may not
373 # match the device's lunch target.
374 if not args.chroot:
Nikita Putikhin516960e2023-05-31 21:57:38 +0000375 verify_device(device)
Josh Gao043bad72015-09-22 11:43:08 -0700376
377 debug_socket = "/data/local/tmp/debug_socket"
378 pid = None
379 run_cmd = None
380
381 # Fetch binary for -p, -n.
David Pursell639d1c42015-10-20 15:38:32 -0700382 binary_file, pid, run_cmd = handle_switches(args, sysroot)
Josh Gao043bad72015-09-22 11:43:08 -0700383
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000384 vscode_launch_props = None
385 if args.vscode_launch_props:
386 if args.setup_forwarding != "vscode-lldb":
387 raise ValueError('vscode_launch_props requires --setup-forwarding=vscode-lldb')
388 vscode_launch_props = json.loads(args.vscode_launch_props)
389
Josh Gao043bad72015-09-22 11:43:08 -0700390 with binary_file:
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700391 if sys.platform.startswith("linux"):
392 platform_name = "linux-x86"
393 elif sys.platform.startswith("darwin"):
394 platform_name = "darwin-x86"
395 else:
396 sys.exit("Unknown platform: {}".format(sys.platform))
397
Josh Gao043bad72015-09-22 11:43:08 -0700398 arch = gdbrunner.get_binary_arch(binary_file)
399 is64bit = arch.endswith("64")
400
401 # Make sure we have the linker
Pirama Arumuga Nainarf7f95442021-06-30 13:31:41 -0700402 clang_base = 'prebuilts/clang/host'
403 clang_version = read_toolchain_config(root)
Haibo Huange194fce2020-01-06 14:40:27 -0800404 toolchain_path = os.path.join(root, clang_base, platform_name,
405 clang_version)
406 llvm_readobj_path = os.path.join(toolchain_path, "bin", "llvm-readobj")
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700407 interp = gdbrunner.get_binary_interp(binary_file.name, llvm_readobj_path)
408 linker_search_dir = ensure_linker(device, sysroot, interp)
Josh Gao043bad72015-09-22 11:43:08 -0700409
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700410 tracer_pid = get_tracer_pid(device, pid)
411 if tracer_pid == 0:
Peter Collingbourne63bf1082018-12-19 20:51:42 -0800412 cmd_prefix = args.su_cmd
413 if args.env:
414 cmd_prefix += ['env'] + [v[0] for v in args.env]
415
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700416 # Start lldb-server.
417 server_local_path = get_lldb_server_path(root, clang_base, clang_version, arch)
418 server_remote_path = "/data/local/tmp/{}-lldb-server".format(arch)
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700419 gdbrunner.start_gdbserver(
Haibo Huange194fce2020-01-06 14:40:27 -0800420 device, server_local_path, server_remote_path,
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700421 target_pid=pid, run_cmd=run_cmd, debug_socket=debug_socket,
Peter Collingbourneba548262022-03-03 12:17:43 -0800422 port=args.port, run_as_cmd=cmd_prefix, lldb=True, chroot=args.chroot)
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700423 else:
Haibo Huange194fce2020-01-06 14:40:27 -0800424 print(
425 "Connecting to tracing pid {} using local port {}".format(
426 tracer_pid, args.port))
Elliott Hughes89e1ecf2017-06-30 14:03:32 -0700427 gdbrunner.forward_gdbserver_port(device, local=args.port,
428 remote="tcp:{}".format(args.port))
Josh Gao043bad72015-09-22 11:43:08 -0700429
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700430 debugger_path = get_lldb_path(toolchain_path)
431 debugger = args.setup_forwarding or 'lldb'
Haibo Huange194fce2020-01-06 14:40:27 -0800432
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700433 # Generate the lldb script.
Nikita Putikhin516960e2023-05-31 21:57:38 +0000434 setup_commands = generate_setup_script(sysroot=sysroot,
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700435 linker_search_dir=linker_search_dir,
Nikita Putikhin516960e2023-05-31 21:57:38 +0000436 binary_name=binary_file.name,
Alex Light92476652019-01-17 11:18:48 -0800437 is64bit=is64bit,
438 port=args.port,
Nikita Putikhin9aa3bc62023-05-19 20:39:51 +0000439 debugger=debugger,
440 vscode_launch_props=vscode_launch_props)
Josh Gao043bad72015-09-22 11:43:08 -0700441
Alex Lighta8f224d2020-11-10 10:30:19 -0800442 if not args.setup_forwarding:
Alex Light92476652019-01-17 11:18:48 -0800443 # Print a newline to separate our messages from the GDB session.
444 print("")
David Pursell639d1c42015-10-20 15:38:32 -0700445
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700446 # Start lldb.
447 gdbrunner.start_gdb(debugger_path, setup_commands, lldb=True)
Alex Light92476652019-01-17 11:18:48 -0800448 else:
449 print("")
Haibo Huange194fce2020-01-06 14:40:27 -0800450 print(setup_commands)
Alex Light92476652019-01-17 11:18:48 -0800451 print("")
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700452 if args.setup_forwarding == "vscode-lldb":
Haibo Huange194fce2020-01-06 14:40:27 -0800453 print(textwrap.dedent("""
Alex Light92476652019-01-17 11:18:48 -0800454 Paste the above json into .vscode/launch.json and start the debugger as
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700455 normal. Press enter in this terminal once debugging is finished to shut
456 lldb-server down and close all the ports."""))
Alex Light92476652019-01-17 11:18:48 -0800457 else:
Haibo Huange194fce2020-01-06 14:40:27 -0800458 print(textwrap.dedent("""
Elliott Hughes4c8e8752021-06-25 14:23:22 -0700459 Paste the lldb commands above into the lldb frontend to set up the
460 lldb-server connection. Press enter in this terminal once debugging is
461 finished to shut lldb-server down and close all the ports."""))
Alex Light92476652019-01-17 11:18:48 -0800462 print("")
Siarhei Vishniakou9c4f1b32021-12-02 10:43:14 -0800463 input("Press enter to shut down lldb-server")
Josh Gao043bad72015-09-22 11:43:08 -0700464
Ryan Prichard5d1c3cb2019-06-04 16:35:02 -0700465
466def main():
467 try:
468 do_main()
469 finally:
470 global g_temp_dirs
471 for temp_dir in g_temp_dirs:
472 shutil.rmtree(temp_dir)
473
474
Josh Gao043bad72015-09-22 11:43:08 -0700475if __name__ == "__main__":
476 main()