JDevlieghere updated this revision to Diff 513025.
JDevlieghere retitled this revision from "[lldb] Use ObjectFileJSON to create
modules for interactive crashlogs (WIP)" to "[lldb] Use ObjectFileJSON to
create modules for interactive crashlogs".
JDevlieghere edited the summary of this revision.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D148172/new/
https://reviews.llvm.org/D148172
Files:
lldb/examples/python/crashlog.py
lldb/examples/python/scripted_process/crashlog_scripted_process.py
lldb/examples/python/symbolication.py
lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/interactive_crashlog/multithread-test.ips
lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test
Index: lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test
===================================================================
--- lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test
+++ lldb/test/Shell/ScriptInterpreter/Python/Crashlog/skipped_status_interactive_crashlog.test
@@ -41,3 +41,5 @@
# CHECK-NEXT: frame #2: 0x0000000100ec5a87 multithread-test`compute_pow{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x000000019cc7e06b{{.*}} [artificial]
# CHECK: frame #{{[0-9]+}}: 0x000000019cc78e2b{{.*}} [artificial]
+
+image list
Index: lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/interactive_crashlog/multithread-test.ips
===================================================================
--- lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/interactive_crashlog/multithread-test.ips
+++ lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/interactive_crashlog/multithread-test.ips
@@ -478,6 +478,15 @@
"source" : "A",
"base" : 0,
"uuid" : "00000000-0000-0000-0000-000000000000"
+ },
+ {
+ "arch": "arm64",
+ "base": 12345,
+ "name": "bogus.dylib",
+ "path": "/usr/lib/system/bogus.dylib",
+ "size": 1000,
+ "source": "P",
+ "uuid": "11111111-2222-3333-4444-555555555555"
}
],
"userID": 501,
Index: lldb/examples/python/symbolication.py
===================================================================
--- lldb/examples/python/symbolication.py
+++ lldb/examples/python/symbolication.py
@@ -35,6 +35,9 @@
import sys
import time
import uuid
+import json
+import tempfile
+import pathlib
class Address:
@@ -230,6 +233,7 @@
def __init__(self, path, uuid=None):
self.path = path
self.resolved_path = None
+ self.resolve = False
self.resolved = False
self.unavailable = False
self.uuid = uuid
@@ -240,6 +244,7 @@
self.module = None
self.symfile = None
self.slide = None
+ self.symbols = dict()
@classmethod
def InitWithSBTargetAndSBModule(cls, target, module):
@@ -372,14 +377,34 @@
uuid_str = self.get_normalized_uuid_string()
if uuid_str:
self.module = target.AddModule(None, None, uuid_str)
- if not self.module:
+ if not self.module and self.resolve:
self.locate_module_and_debug_symbols()
- if self.unavailable:
- return None
- resolved_path = self.get_resolved_path()
- self.module = target.AddModule(
- resolved_path, None, uuid_str, self.symfile)
- if not self.module:
+ if not self.unavailable:
+ resolved_path = self.get_resolved_path()
+ self.module = target.AddModule(
+ resolved_path, None, uuid_str, self.symfile)
+ if not self.module and self.section_infos:
+ name = pathlib.Path(self.path).name
+ with tempfile.NamedTemporaryFile(suffix='.' + name) as tf:
+ data = {
+ 'triple': target.triple,
+ 'uuid': uuid_str,
+ 'type': 'sharedlibrary',
+ 'sections': list(),
+ 'symbols': list()
+ }
+ for section in self.section_infos:
+ data['sections'].append({
+ 'name' : section.name,
+ 'address': 0,
+ 'size': section.end_addr - section.start_addr
+ })
+ for symbol in self.symbols.values():
+ data['symbols'].append(symbol)
+ with open(tf.name, 'w') as f:
+ f.write(json.dumps(data, indent=4))
+ self.module = target.AddModule(tf.name, None, uuid_str)
+ if not self.module and not self.unavailable:
return 'error: unable to get module for (%s) "%s"' % (
self.arch, self.get_resolved_path())
if self.has_section_load_info():
Index: lldb/examples/python/scripted_process/crashlog_scripted_process.py
===================================================================
--- lldb/examples/python/scripted_process/crashlog_scripted_process.py
+++ lldb/examples/python/scripted_process/crashlog_scripted_process.py
@@ -22,27 +22,28 @@
if hasattr(self.crashlog, 'asb'):
self.extended_thread_info = self.crashlog.asb
- def load_images(self, images):
- #TODO: Add to self.loaded_images and load images in lldb
- if images:
- for image in images:
- if image not in self.loaded_images:
- if image.uuid == uuid.UUID(int=0):
- continue
- err = image.add_module(self.target)
- if err:
- # Append to SBCommandReturnObject
- print(err)
- else:
- self.loaded_images.append(image)
+ if self.load_all_images:
+ for image in self.crashlog.images:
+ image.resolve = True
+ else:
+ for thread in self.crashlog.threads:
+ if thread.did_crash():
+ for ident in thread.idents:
+ for image in self.crashlog.find_images_with_identifier(ident):
+ image.resolve = True
+
+ for image in self.crashlog.images:
+ if image not in self.loaded_images:
+ if image.uuid == uuid.UUID(int=0):
+ continue
+ err = image.add_module(self.target)
+ if err:
+ # Append to SBCommandReturnObject
+ print(err)
+ else:
+ self.loaded_images.append(image)
for thread in self.crashlog.threads:
- if self.load_all_images:
- load_images(self, self.crashlog.images)
- elif thread.did_crash():
- for ident in thread.idents:
- load_images(self, self.crashlog.find_images_with_identifier(ident))
-
if hasattr(thread, 'app_specific_backtrace') and thread.app_specific_backtrace:
# We don't want to include the Application Specific Backtrace
# Thread into the Scripted Process' Thread list.
Index: lldb/examples/python/crashlog.py
===================================================================
--- lldb/examples/python/crashlog.py
+++ lldb/examples/python/crashlog.py
@@ -80,6 +80,7 @@
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 @@
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,8 +512,7 @@
exception_extra)
def parse_images(self, json_images):
- idx = 0
- for json_image in json_images:
+ for idx, json_image in enumerate(json_images):
img_uuid = uuid.UUID(json_image['uuid'])
low = int(json_image['base'])
high = low + int(
@@ -518,8 +523,8 @@
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,18 @@
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",
+ "size": 0x0,
+ "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 +1032,25 @@
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):
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits