Mike Frysinger | f1ba7ad | 2022-09-12 05:42:57 -0400 | [diff] [blame^] | 1 | # Copyright 2013 The ChromiumOS Authors |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | """Generate minidump symbols for use by the Crash server. |
| 6 | |
| 7 | Note: This should be run inside the chroot. |
| 8 | |
| 9 | This produces files in the breakpad format required by minidump_stackwalk and |
| 10 | the crash server to dump stack information. |
| 11 | |
| 12 | Basically it scans all the split .debug files in /build/$BOARD/usr/lib/debug/ |
| 13 | and converts them over using the `dump_syms` programs. Those plain text .sym |
| 14 | files are then stored in /build/$BOARD/usr/lib/debug/breakpad/. |
| 15 | |
Mike Frysinger | 02e1e07 | 2013-11-10 22:11:34 -0500 | [diff] [blame] | 16 | If you want to actually upload things, see upload_symbols.py. |
| 17 | """ |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 18 | |
| 19 | import collections |
| 20 | import ctypes |
Chris McDonald | b55b703 | 2021-06-17 16:41:32 -0600 | [diff] [blame] | 21 | import logging |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 22 | import multiprocessing |
| 23 | import os |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 24 | |
Chris McDonald | b55b703 | 2021-06-17 16:41:32 -0600 | [diff] [blame] | 25 | from chromite.cbuildbot import cbuildbot_alerts |
Mike Frysinger | 06a51c8 | 2021-04-06 11:39:17 -0400 | [diff] [blame] | 26 | from chromite.lib import build_target_lib |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 27 | from chromite.lib import commandline |
| 28 | from chromite.lib import cros_build_lib |
| 29 | from chromite.lib import osutils |
| 30 | from chromite.lib import parallel |
Mike Frysinger | 96ad3f2 | 2014-04-24 23:27:27 -0400 | [diff] [blame] | 31 | from chromite.lib import signals |
Alex Klein | 1809f57 | 2021-09-09 11:28:37 -0600 | [diff] [blame] | 32 | from chromite.utils import file_util |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 33 | |
Mike Frysinger | 807d828 | 2022-04-28 22:45:17 -0400 | [diff] [blame] | 34 | |
Stephen Boyd | fc1c803 | 2021-10-06 20:58:37 -0700 | [diff] [blame] | 35 | # Elf files that don't exist but have a split .debug file installed. |
| 36 | ALLOWED_DEBUG_ONLY_FILES = { |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 37 | "boot/vmlinux", |
Stephen Boyd | fc1c803 | 2021-10-06 20:58:37 -0700 | [diff] [blame] | 38 | } |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 39 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 40 | SymbolHeader = collections.namedtuple( |
| 41 | "SymbolHeader", |
| 42 | ( |
| 43 | "cpu", |
| 44 | "id", |
| 45 | "name", |
| 46 | "os", |
| 47 | ), |
| 48 | ) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 49 | |
| 50 | |
| 51 | def ReadSymsHeader(sym_file): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 52 | """Parse the header of the symbol file |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 53 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 54 | The first line of the syms file will read like: |
| 55 | MODULE Linux arm F4F6FA6CCBDEF455039C8DE869C8A2F40 blkid |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 56 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 57 | https://code.google.com/p/google-breakpad/wiki/SymbolFiles |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 58 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 59 | Args: |
| 60 | sym_file: The symbol file to parse |
Mike Frysinger | 1a736a8 | 2013-12-12 01:50:59 -0500 | [diff] [blame] | 61 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 62 | Returns: |
| 63 | A SymbolHeader object |
Mike Frysinger | 1a736a8 | 2013-12-12 01:50:59 -0500 | [diff] [blame] | 64 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 65 | Raises: |
| 66 | ValueError if the first line of |sym_file| is invalid |
| 67 | """ |
| 68 | with file_util.Open(sym_file, "rb") as f: |
| 69 | header = f.readline().decode("utf-8").split() |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 70 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 71 | if header[0] != "MODULE" or len(header) != 5: |
| 72 | raise ValueError("header of sym file is invalid") |
Mike Frysinger | 50cedd3 | 2014-02-09 23:03:18 -0500 | [diff] [blame] | 73 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 74 | return SymbolHeader( |
| 75 | os=header[1], cpu=header[2], id=header[3], name=header[4] |
| 76 | ) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 77 | |
| 78 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 79 | def GenerateBreakpadSymbol( |
| 80 | elf_file, |
| 81 | debug_file=None, |
| 82 | breakpad_dir=None, |
| 83 | strip_cfi=False, |
| 84 | num_errors=None, |
| 85 | dump_syms_cmd="dump_syms", |
| 86 | ): |
| 87 | """Generate the symbols for |elf_file| using |debug_file| |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 88 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 89 | Args: |
| 90 | elf_file: The file to dump symbols for |
| 91 | debug_file: Split debug file to use for symbol information |
| 92 | breakpad_dir: The dir to store the output symbol file in |
| 93 | strip_cfi: Do not generate CFI data |
| 94 | num_errors: An object to update with the error count (needs a .value member) |
| 95 | dump_syms_cmd: Command to use for dumping symbols. |
Mike Frysinger | 1a736a8 | 2013-12-12 01:50:59 -0500 | [diff] [blame] | 96 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 97 | Returns: |
| 98 | The name of symbol file written out on success, or the failure count. |
| 99 | """ |
| 100 | assert breakpad_dir |
| 101 | if num_errors is None: |
| 102 | num_errors = ctypes.c_int() |
| 103 | debug_file_only = not os.path.exists(elf_file) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 104 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 105 | cmd_base = [dump_syms_cmd, "-v"] |
| 106 | if strip_cfi: |
| 107 | cmd_base += ["-c"] |
| 108 | # Some files will not be readable by non-root (e.g. set*id /bin/su). |
| 109 | needs_sudo = not os.access(elf_file, os.R_OK) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 110 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 111 | def _DumpIt(cmd_args): |
| 112 | if needs_sudo: |
| 113 | run_command = cros_build_lib.sudo_run |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 114 | else: |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 115 | run_command = cros_build_lib.run |
| 116 | return run_command( |
| 117 | cmd_base + cmd_args, |
| 118 | stderr=True, |
| 119 | stdout=temp.name, |
| 120 | check=False, |
| 121 | debug_level=logging.DEBUG, |
| 122 | ) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 123 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 124 | def _CrashCheck(result, file_or_files, msg): |
| 125 | if result.returncode: |
| 126 | cbuildbot_alerts.PrintBuildbotStepWarnings() |
| 127 | if result.returncode < 0: |
| 128 | logging.warning( |
| 129 | "dump_syms %s crashed with %s; %s", |
| 130 | file_or_files, |
| 131 | signals.StrSignal(-result.returncode), |
| 132 | msg, |
| 133 | ) |
| 134 | else: |
| 135 | logging.warning( |
| 136 | "dump_syms %s returned %d; %s", |
| 137 | file_or_files, |
| 138 | result.returncode, |
| 139 | msg, |
| 140 | ) |
| 141 | logging.warning("output:\n%s", result.stderr.decode("utf-8")) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 142 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 143 | osutils.SafeMakedirs(breakpad_dir) |
| 144 | with cros_build_lib.UnbufferedNamedTemporaryFile( |
| 145 | dir=breakpad_dir, delete=False |
| 146 | ) as temp: |
| 147 | if debug_file: |
| 148 | # Try to dump the symbols using the debug file like normal. |
| 149 | if debug_file_only: |
| 150 | cmd_args = [debug_file] |
| 151 | file_or_files = debug_file |
| 152 | else: |
| 153 | cmd_args = [elf_file, os.path.dirname(debug_file)] |
| 154 | file_or_files = [elf_file, debug_file] |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 155 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 156 | result = _DumpIt(cmd_args) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 157 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 158 | if result.returncode: |
| 159 | # Sometimes dump_syms can crash because there's too much info. |
| 160 | # Try dumping and stripping the extended stuff out. At least |
| 161 | # this way we'll get the extended symbols. https://crbug.com/266064 |
| 162 | _CrashCheck(result, file_or_files, "retrying w/out CFI") |
| 163 | cmd_args = ["-c", "-r"] + cmd_args |
| 164 | result = _DumpIt(cmd_args) |
| 165 | _CrashCheck(result, file_or_files, "retrying w/out debug") |
Prathmesh Prabhu | 9995e9b | 2013-10-31 16:43:55 -0700 | [diff] [blame] | 166 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 167 | basic_dump = result.returncode |
Prathmesh Prabhu | 9995e9b | 2013-10-31 16:43:55 -0700 | [diff] [blame] | 168 | else: |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 169 | basic_dump = True |
Prathmesh Prabhu | 9995e9b | 2013-10-31 16:43:55 -0700 | [diff] [blame] | 170 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 171 | if basic_dump: |
| 172 | # If that didn't work (no debug, or dump_syms still failed), try |
| 173 | # dumping just the file itself directly. |
| 174 | result = _DumpIt([elf_file]) |
| 175 | if result.returncode: |
| 176 | # A lot of files (like kernel files) contain no debug information, |
| 177 | # do not consider such occurrences as errors. |
| 178 | cbuildbot_alerts.PrintBuildbotStepWarnings() |
| 179 | if b"file contains no debugging information" in result.stderr: |
| 180 | logging.warning("dump_syms failed; giving up entirely.") |
| 181 | logging.warning("No symbols found for %s", elf_file) |
| 182 | else: |
| 183 | num_errors.value += 1 |
| 184 | _CrashCheck(result, elf_file, "giving up entirely") |
| 185 | os.unlink(temp.name) |
| 186 | return num_errors.value |
Prathmesh Prabhu | 9995e9b | 2013-10-31 16:43:55 -0700 | [diff] [blame] | 187 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 188 | # Move the dumped symbol file to the right place: |
| 189 | # /build/$BOARD/usr/lib/debug/breakpad/<module-name>/<id>/<module-name>.sym |
| 190 | header = ReadSymsHeader(temp) |
| 191 | logging.info("Dumped %s as %s : %s", elf_file, header.name, header.id) |
| 192 | sym_file = os.path.join( |
| 193 | breakpad_dir, header.name, header.id, header.name + ".sym" |
| 194 | ) |
| 195 | osutils.SafeMakedirs(os.path.dirname(sym_file)) |
| 196 | os.rename(temp.name, sym_file) |
| 197 | os.chmod(sym_file, 0o644) |
Prathmesh Prabhu | 9995e9b | 2013-10-31 16:43:55 -0700 | [diff] [blame] | 198 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 199 | return sym_file |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 200 | |
Prathmesh Prabhu | 9995e9b | 2013-10-31 16:43:55 -0700 | [diff] [blame] | 201 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 202 | def GenerateBreakpadSymbols( |
| 203 | board, |
| 204 | breakpad_dir=None, |
| 205 | strip_cfi=False, |
| 206 | generate_count=None, |
| 207 | sysroot=None, |
| 208 | num_processes=None, |
| 209 | clean_breakpad=False, |
| 210 | exclude_dirs=(), |
| 211 | file_list=None, |
| 212 | ): |
| 213 | """Generate symbols for this board. |
Prathmesh Prabhu | 9995e9b | 2013-10-31 16:43:55 -0700 | [diff] [blame] | 214 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 215 | If |file_list| is None, symbols are generated for all executables, otherwise |
| 216 | only for the files included in |file_list|. |
Prathmesh Prabhu | 9995e9b | 2013-10-31 16:43:55 -0700 | [diff] [blame] | 217 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 218 | TODO(build): |
| 219 | This should be merged with buildbot_commands.GenerateBreakpadSymbols() |
| 220 | once we rewrite cros_generate_breakpad_symbols in python. |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 221 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 222 | Args: |
| 223 | board: The board whose symbols we wish to generate |
| 224 | breakpad_dir: The full path to the breakpad directory where symbols live |
| 225 | strip_cfi: Do not generate CFI data |
| 226 | generate_count: If set, only generate this many symbols (meant for testing) |
| 227 | sysroot: The root where to find the corresponding ELFs |
| 228 | num_processes: Number of jobs to run in parallel |
| 229 | clean_breakpad: Should we `rm -rf` the breakpad output dir first; note: we |
| 230 | do not do any locking, so do not run more than one in parallel when True |
| 231 | exclude_dirs: List of dirs (relative to |sysroot|) to not search |
| 232 | file_list: Only generate symbols for files in this list. Each file must be a |
| 233 | full path (including |sysroot| prefix). |
| 234 | TODO(build): Support paths w/o |sysroot|. |
| 235 | |
| 236 | Returns: |
| 237 | The number of errors that were encountered. |
| 238 | """ |
| 239 | if sysroot is None: |
| 240 | sysroot = build_target_lib.get_default_sysroot_path(board) |
| 241 | if breakpad_dir is None: |
| 242 | breakpad_dir = FindBreakpadDir(board, sysroot=sysroot) |
| 243 | if clean_breakpad: |
| 244 | logging.info("cleaning out %s first", breakpad_dir) |
| 245 | osutils.RmDir(breakpad_dir, ignore_missing=True, sudo=True) |
| 246 | # Make sure non-root can write out symbols as needed. |
| 247 | osutils.SafeMakedirs(breakpad_dir, sudo=True) |
| 248 | if not os.access(breakpad_dir, os.W_OK): |
| 249 | cros_build_lib.sudo_run(["chown", "-R", str(os.getuid()), breakpad_dir]) |
| 250 | debug_dir = FindDebugDir(board, sysroot=sysroot) |
| 251 | exclude_paths = [os.path.join(debug_dir, x) for x in exclude_dirs] |
| 252 | if file_list is None: |
| 253 | file_list = [] |
| 254 | file_filter = dict.fromkeys([os.path.normpath(x) for x in file_list], False) |
| 255 | |
| 256 | logging.info("generating breakpad symbols using %s", debug_dir) |
| 257 | |
| 258 | # Let's locate all the debug_files and elfs first along with the debug file |
| 259 | # sizes. This way we can start processing the largest files first in parallel |
| 260 | # with the small ones. |
| 261 | # If |file_list| was given, ignore all other files. |
| 262 | targets = [] |
| 263 | for root, dirs, files in os.walk(debug_dir): |
| 264 | if root in exclude_paths: |
| 265 | logging.info("Skipping excluded dir %s", root) |
| 266 | del dirs[:] |
| 267 | continue |
| 268 | |
| 269 | for debug_file in files: |
| 270 | debug_file = os.path.join(root, debug_file) |
| 271 | # Turn /build/$BOARD/usr/lib/debug/sbin/foo.debug into |
| 272 | # /build/$BOARD/sbin/foo. |
| 273 | elf_file = os.path.join( |
| 274 | sysroot, debug_file[len(debug_dir) + 1 : -6] |
| 275 | ) |
| 276 | |
| 277 | if file_filter: |
| 278 | if elf_file in file_filter: |
| 279 | file_filter[elf_file] = True |
| 280 | elif debug_file in file_filter: |
| 281 | file_filter[debug_file] = True |
| 282 | else: |
| 283 | continue |
| 284 | |
| 285 | # Filter out files based on common issues with the debug file. |
| 286 | if not debug_file.endswith(".debug"): |
| 287 | continue |
| 288 | |
| 289 | elif os.path.islink(debug_file): |
| 290 | # The build-id stuff is common enough to filter out by default. |
| 291 | if "/.build-id/" in debug_file: |
| 292 | msg = logging.debug |
| 293 | else: |
| 294 | msg = logging.warning |
| 295 | msg("Skipping symbolic link %s", debug_file) |
| 296 | continue |
| 297 | |
| 298 | # Filter out files based on common issues with the elf file. |
| 299 | elf_path = os.path.relpath(elf_file, sysroot) |
| 300 | debug_only = elf_path in ALLOWED_DEBUG_ONLY_FILES |
| 301 | if not os.path.exists(elf_file) and not debug_only: |
| 302 | # Sometimes we filter out programs from /usr/bin but leave behind |
| 303 | # the .debug file. |
| 304 | logging.warning("Skipping missing %s", elf_file) |
| 305 | continue |
| 306 | |
| 307 | targets.append((os.path.getsize(debug_file), elf_file, debug_file)) |
| 308 | |
| 309 | bg_errors = parallel.WrapMultiprocessing(multiprocessing.Value, "i") |
| 310 | if file_filter: |
| 311 | files_not_found = [x for x, found in file_filter.items() if not found] |
| 312 | bg_errors.value += len(files_not_found) |
| 313 | if files_not_found: |
| 314 | logging.error("Failed to find requested files: %s", files_not_found) |
| 315 | |
| 316 | # Now start generating symbols for the discovered elfs. |
| 317 | with parallel.BackgroundTaskRunner( |
| 318 | GenerateBreakpadSymbol, |
| 319 | breakpad_dir=breakpad_dir, |
| 320 | strip_cfi=strip_cfi, |
| 321 | num_errors=bg_errors, |
| 322 | processes=num_processes, |
| 323 | ) as queue: |
| 324 | for _, elf_file, debug_file in sorted(targets, reverse=True): |
| 325 | if generate_count == 0: |
| 326 | break |
| 327 | |
| 328 | queue.put([elf_file, debug_file]) |
| 329 | if generate_count is not None: |
| 330 | generate_count -= 1 |
| 331 | if generate_count == 0: |
| 332 | break |
| 333 | |
| 334 | return bg_errors.value |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 335 | |
| 336 | |
Mike Frysinger | 3f571af | 2016-08-31 23:56:53 -0400 | [diff] [blame] | 337 | def FindDebugDir(board, sysroot=None): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 338 | """Given a |board|, return the path to the split debug dir for it""" |
| 339 | if sysroot is None: |
| 340 | sysroot = build_target_lib.get_default_sysroot_path(board) |
| 341 | return os.path.join(sysroot, "usr", "lib", "debug") |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 342 | |
| 343 | |
Mike Frysinger | 3f571af | 2016-08-31 23:56:53 -0400 | [diff] [blame] | 344 | def FindBreakpadDir(board, sysroot=None): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 345 | """Given a |board|, return the path to the breakpad dir for it""" |
| 346 | return os.path.join(FindDebugDir(board, sysroot=sysroot), "breakpad") |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 347 | |
| 348 | |
| 349 | def main(argv): |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 350 | parser = commandline.ArgumentParser(description=__doc__) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 351 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 352 | parser.add_argument( |
| 353 | "--board", default=None, help="board to generate symbols for" |
| 354 | ) |
| 355 | parser.add_argument( |
| 356 | "--breakpad_root", |
| 357 | type="path", |
| 358 | default=None, |
| 359 | help="root output directory for breakpad symbols", |
| 360 | ) |
| 361 | parser.add_argument( |
| 362 | "--sysroot", |
| 363 | type="path", |
| 364 | default=None, |
| 365 | help="root input directory for files", |
| 366 | ) |
| 367 | parser.add_argument( |
| 368 | "--exclude-dir", |
| 369 | type=str, |
| 370 | action="append", |
| 371 | default=[], |
| 372 | help="directory (relative to |board| root) to not search", |
| 373 | ) |
| 374 | parser.add_argument( |
| 375 | "--generate-count", |
| 376 | type=int, |
| 377 | default=None, |
| 378 | help="only generate # number of symbols", |
| 379 | ) |
| 380 | parser.add_argument( |
| 381 | "--noclean", |
| 382 | dest="clean", |
| 383 | action="store_false", |
| 384 | default=True, |
| 385 | help="do not clean out breakpad dir before running", |
| 386 | ) |
| 387 | parser.add_argument( |
| 388 | "--jobs", type=int, default=None, help="limit number of parallel jobs" |
| 389 | ) |
| 390 | parser.add_argument( |
| 391 | "--strip_cfi", |
| 392 | action="store_true", |
| 393 | default=False, |
| 394 | help="do not generate CFI data (pass -c to dump_syms)", |
| 395 | ) |
| 396 | parser.add_argument( |
| 397 | "file_list", |
| 398 | nargs="*", |
| 399 | default=None, |
| 400 | help="generate symbols for only these files " |
| 401 | "(e.g. /build/$BOARD/usr/bin/foo)", |
| 402 | ) |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 403 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 404 | opts = parser.parse_args(argv) |
| 405 | opts.Freeze() |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 406 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 407 | if opts.board is None and opts.sysroot is None: |
| 408 | cros_build_lib.Die("--board or --sysroot is required") |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 409 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 410 | ret = GenerateBreakpadSymbols( |
| 411 | opts.board, |
| 412 | breakpad_dir=opts.breakpad_root, |
| 413 | strip_cfi=opts.strip_cfi, |
| 414 | generate_count=opts.generate_count, |
| 415 | sysroot=opts.sysroot, |
| 416 | num_processes=opts.jobs, |
| 417 | clean_breakpad=opts.clean, |
| 418 | exclude_dirs=opts.exclude_dir, |
| 419 | file_list=opts.file_list, |
| 420 | ) |
| 421 | if ret: |
| 422 | logging.error("encountered %i problem(s)", ret) |
| 423 | # Since exit(status) gets masked, clamp it to 1 so we don't inadvertently |
| 424 | # return 0 in case we are a multiple of the mask. |
| 425 | ret = 1 |
Mike Frysinger | 69cb41d | 2013-08-11 20:08:19 -0400 | [diff] [blame] | 426 | |
Alex Klein | 1699fab | 2022-09-08 08:46:06 -0600 | [diff] [blame] | 427 | return ret |