diff options
author | Jonas Devlieghere <jonas@devlieghere.com> | 2023-04-13 16:27:53 -0700 |
---|---|---|
committer | Jonas Devlieghere <jonas@devlieghere.com> | 2023-04-13 16:56:29 -0700 |
commit | 27f27d15f6c90b026eca23b8ee238fdbf772fd80 (patch) | |
tree | 8fd3e01ed2d4b472361cba530f4181ec5bffee6f /lldb/examples/python/crashlog.py | |
parent | fcc5f9ef50e18137fd8020127db05a59c3a4015d (diff) | |
download | llvm-27f27d15f6c90b026eca23b8ee238fdbf772fd80.zip llvm-27f27d15f6c90b026eca23b8ee238fdbf772fd80.tar.gz llvm-27f27d15f6c90b026eca23b8ee238fdbf772fd80.tar.bz2 |
[lldb] Use ObjectFileJSON to create modules for interactive crashlogs
Create an artificial module using a JSON object file when we can't
locate the module and dSYM through dsymForUUID (or however
locate_module_and_debug_symbols is implemented). By parsing the symbols
from the crashlog and making them part of the JSON object file, LLDB can
symbolicate frames it otherwise wouldn't be able to, as there is no
module for it.
For non-interactive crashlogs, that never was a problem because we could
simply show the "pre-symbolicated" frame from the input. For interactive
crashlogs, we need a way to pass the symbol information to LLDB so that
it can symbolicate the frames, which is what motivated the JSON object
file format.
Differential revision: https://reviews.llvm.org/D148172
Diffstat (limited to 'lldb/examples/python/crashlog.py')
-rwxr-xr-x | lldb/examples/python/crashlog.py | 57 |
1 files changed, 29 insertions, 28 deletions
diff --git a/lldb/examples/python/crashlog.py b/lldb/examples/python/crashlog.py index 68ead43..dadab3c 100755 --- a/lldb/examples/python/crashlog.py +++ b/lldb/examples/python/crashlog.py @@ -80,6 +80,7 @@ class CrashLog(symbolication.Symbolicator): def __init__(self, index, app_specific_backtrace): self.index = index self.id = index + self.images = list() self.frames = list() self.idents = list() self.registers = dict() @@ -456,6 +457,11 @@ class JSONCrashLogParser(CrashLogParser): except: return None + def __init__(self, debugger, path, verbose): + super().__init__(debugger, path, verbose) + # List of DarwinImages sorted by their index. + self.images = list() + def parse(self): try: self.parse_process_info(self.data) @@ -506,7 +512,6 @@ class JSONCrashLogParser(CrashLogParser): exception_extra) def parse_images(self, json_images): - idx = 0 for json_image in json_images: img_uuid = uuid.UUID(json_image['uuid']) low = int(json_image['base']) @@ -518,8 +523,8 @@ class JSONCrashLogParser(CrashLogParser): darwin_image = self.crashlog.DarwinImage(low, high, name, version, img_uuid, path, self.verbose) + self.images.append(darwin_image) self.crashlog.images.append(darwin_image) - idx += 1 def parse_main_image(self, json_data): if 'procName' in json_data: @@ -539,6 +544,17 @@ class JSONCrashLogParser(CrashLogParser): frame_offset = int(json_frame['imageOffset']) image_addr = self.get_used_image(image_id)['base'] pc = image_addr + frame_offset + + if 'symbol' in json_frame: + symbol = json_frame['symbol'] + location = int(json_frame['symbolLocation']) + image = self.images[image_id] + image.symbols[symbol] = { + "name": symbol, + "type": "code", + "address": frame_offset - location + } + thread.frames.append(self.crashlog.Frame(idx, pc, frame_offset)) # on arm64 systems, if it jump through a null function pointer, @@ -1015,40 +1031,25 @@ def SymbolicateCrashLog(crash_log, options): target = crash_log.create_target() if not target: return - exe_module = target.GetModuleAtIndex(0) - images_to_load = list() - loaded_images = list() + + if options.load_all_images: - # --load-all option was specified, load everything up for image in crash_log.images: - images_to_load.append(image) - else: - # Only load the images found in stack frames for the crashed threads - if options.crashed_only: - for thread in crash_log.threads: - if thread.did_crash(): - for ident in thread.idents: - images = crash_log.find_images_with_identifier(ident) - if images: - for image in images: - images_to_load.append(image) - else: - print('error: can\'t find image for identifier "%s"' % ident) - else: - for ident in crash_log.idents: - images = crash_log.find_images_with_identifier(ident) - if images: - for image in images: - images_to_load.append(image) - else: - print('error: can\'t find image for identifier "%s"' % ident) + image.resolve = True + elif options.crashed_only: + for thread in crash_log.threads: + if thread.did_crash(): + for ident in thread.idents: + for image in self.crashlog.find_images_with_identifier(ident): + image.resolve = True futures = [] + loaded_images = [] with concurrent.futures.ThreadPoolExecutor() as executor: def add_module(image, target): return image, image.add_module(target) - for image in images_to_load: + for image in crash_log.images: futures.append(executor.submit(add_module, image=image, target=target)) for future in concurrent.futures.as_completed(futures): |