| # Copyright 2018 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| python |
| |
| import os |
| import subprocess |
| import sys |
| |
| compile_dirs = set() |
| src_dir = None |
| |
| def get_current_debug_file_directories(): |
| dir = gdb.execute("show debug-file-directory", to_string=True) |
| dir = dir[ |
| len('The directory where separate debug symbols are searched for is "' |
| ):-len('".') - 1] |
| return set(dir.split(":")) |
| |
| |
| def add_debug_file_directory(dir): |
| # gdb has no function to add debug-file-directory, simulates that by using |
| # `show debug-file-directory` and `set debug-file-directory <directories>`. |
| current_dirs = get_current_debug_file_directories() |
| current_dirs.add(dir) |
| gdb.execute( |
| "set debug-file-directory %s" % ":".join(current_dirs), to_string=True) |
| |
| |
| def load_libcxx_pretty_printers(src_dir): |
| libcxx_pretty_printers = os.path.join(src_dir, 'third_party', 'libc++', 'src', |
| 'utils', 'gdb', 'libcxx') |
| if not os.path.isdir(libcxx_pretty_printers): |
| return |
| sys.path.insert(1, libcxx_pretty_printers) |
| from printers import register_libcxx_printer_loader |
| register_libcxx_printer_loader() |
| |
| |
| def load_gdb_chrome(src_dir): |
| tools_gdb = os.path.join(src_dir, 'tools', 'gdb') |
| |
| sys.path.insert(1, tools_gdb) |
| import gdb_chrome |
| |
| gdb.execute('source %s' % os.path.join(tools_gdb, 'viewg.gdb')) |
| |
| |
| def set_src_dir(compile_dir): |
| global src_dir |
| git = subprocess.Popen( |
| ['git', '-C', compile_dir, 'rev-parse', '--show-toplevel'], |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE) |
| src_dir, _ = git.communicate() |
| if git.returncode: |
| return |
| if isinstance(src_dir, str): |
| src_dir = src_dir.rstrip() |
| else: |
| src_dir = src_dir.decode('utf-8').rstrip() |
| |
| # If there's no chrome directory in the repo root, we got the wrong git repo. |
| # The most common way to have this happen is to be in a git checkout of |
| # another project that vendors chromium in its own third_party directory. In |
| # that case, try falling back to the current working directory. |
| if not os.path.isdir(os.path.join(src_dir, 'chrome')): |
| src_dir = os.path.abspath(os.getcwd()) |
| |
| load_libcxx_pretty_printers(src_dir) |
| |
| load_gdb_chrome(src_dir) |
| |
| |
| def newobj_handler(event): |
| global compile_dirs |
| compile_dir = os.path.dirname(event.new_objfile.filename) |
| if not compile_dir: |
| return |
| if compile_dir in compile_dirs: |
| return |
| compile_dirs.add(compile_dir) |
| |
| # Add source path |
| gdb.execute("dir %s" % compile_dir) |
| |
| # Need to tell the location of .dwo files. |
| # https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html |
| # https://crbug.com/603286#c35 |
| add_debug_file_directory(compile_dir) |
| |
| global src_dir |
| if not src_dir: |
| set_src_dir(compile_dir) |
| |
| |
| # Event hook for newly loaded objfiles. |
| # https://sourceware.org/gdb/onlinedocs/gdb/Events-In-Python.html |
| gdb.events.new_objfile.connect(newobj_handler) |
| |
| gdb.execute("set environment CHROMIUM_GDBINIT_SOURCED=1") |
| |
| # GDB 9.1 adds a setting, disabled by default, to do multithreaded symbol |
| # loading. This is a major speed up for Chrome, so turn it on here. We |
| # use try..except to avoid displaying errors in earlier GDB versions. |
| try: |
| # unlimited means "number of cores" |
| gdb.execute("maint set worker-threads unlimited") |
| except: |
| pass |
| |
| end |