mib updated this revision to Diff 511805.
mib marked 7 inline comments as done and an inline comment as not done.
mib added a comment.
Address some of the comments.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D146765/new/
https://reviews.llvm.org/D146765
Files:
lldb/examples/python/crashlog.py
lldb/include/lldb/API/SBModuleSpec.h
lldb/include/lldb/API/SBTarget.h
lldb/source/API/SBModuleSpec.cpp
lldb/source/API/SBTarget.cpp
Index: lldb/source/API/SBTarget.cpp
===================================================================
--- lldb/source/API/SBTarget.cpp
+++ lldb/source/API/SBTarget.cpp
@@ -1555,6 +1555,19 @@
return sb_module;
}
+SBModule SBTarget::FindModule(const SBModuleSpec &sb_module_spec) {
+ LLDB_INSTRUMENT_VA(this, sb_module_spec);
+
+ SBModule sb_module;
+ TargetSP target_sp(GetSP());
+ if (target_sp && sb_module_spec.IsValid()) {
+ // The module list is thread safe, no need to lock
+ sb_module.SetSP(
+ target_sp->GetImages().FindFirstModule(*sb_module_spec.m_opaque_up));
+ }
+ return sb_module;
+}
+
SBSymbolContextList SBTarget::FindCompileUnits(const SBFileSpec &sb_file_spec) {
LLDB_INSTRUMENT_VA(this, sb_file_spec);
Index: lldb/source/API/SBModuleSpec.cpp
===================================================================
--- lldb/source/API/SBModuleSpec.cpp
+++ lldb/source/API/SBModuleSpec.cpp
@@ -132,6 +132,13 @@
return m_opaque_up->GetUUID().GetBytes().size();
}
+bool SBModuleSpec::SetUUIDFromString(const char *uuid) {
+ LLDB_INSTRUMENT_VA(this, uuid)
+
+ m_opaque_up->GetUUID().SetFromStringRef(llvm::StringRef(uuid));
+ return m_opaque_up->GetUUID().IsValid();
+}
+
bool SBModuleSpec::SetUUIDBytes(const uint8_t *uuid, size_t uuid_len) {
LLDB_INSTRUMENT_VA(this, uuid, uuid_len)
m_opaque_up->GetUUID() = UUID(uuid, uuid_len);
Index: lldb/include/lldb/API/SBTarget.h
===================================================================
--- lldb/include/lldb/API/SBTarget.h
+++ lldb/include/lldb/API/SBTarget.h
@@ -305,6 +305,8 @@
lldb::SBModule FindModule(const lldb::SBFileSpec &file_spec);
+ lldb::SBModule FindModule(const lldb::SBModuleSpec &module_spec);
+
/// Find compile units related to *this target and passed source
/// file.
///
Index: lldb/include/lldb/API/SBModuleSpec.h
===================================================================
--- lldb/include/lldb/API/SBModuleSpec.h
+++ lldb/include/lldb/API/SBModuleSpec.h
@@ -75,6 +75,8 @@
size_t GetUUIDLength();
+ bool SetUUIDFromString(const char *uuid);
+
bool SetUUIDBytes(const uint8_t *uuid, size_t uuid_len);
bool GetDescription(lldb::SBStream &description);
Index: lldb/examples/python/crashlog.py
===================================================================
--- lldb/examples/python/crashlog.py
+++ lldb/examples/python/crashlog.py
@@ -40,6 +40,7 @@
import string
import subprocess
import sys
+import tempfile
import threading
import time
import uuid
@@ -431,6 +432,7 @@
self.path = os.path.expanduser(path)
self.verbose = verbose
self.crashlog = CrashLog(debugger, self.path, self.verbose)
+ self.symbol_data = {}
@abc.abstractmethod
def parse(self):
@@ -536,8 +538,22 @@
self.crashlog.idents.append(ident)
frame_offset = int(json_frame['imageOffset'])
- image_addr = self.get_used_image(image_id)['base']
- pc = image_addr + frame_offset
+ pc = json_image['base'] + frame_offset
+
+ if 'symbol' in json_frame and pc != 0:
+ image_uuid = json_image['uuid']
+ if not image_uuid in self.symbol_data:
+ self.symbol_data[image_uuid] = {
+ "symbols" : list(),
+ "uuid": image_uuid,
+ "triple": None
+ }
+ self.symbol_data[image_uuid]["symbols"].append({
+ "name": json_frame['symbol'],
+ "type": "code",
+ "size": 0,
+ "address": pc - frame_offset,
+ })
thread.frames.append(self.crashlog.Frame(idx, pc, frame_offset))
# on arm64 systems, if it jump through a null function pointer,
@@ -586,8 +602,12 @@
print("error: can't parse application specific backtrace.")
return False
- (frame_id, frame_img_name, frame_addr,
- frame_ofs) = frame_match.groups()
+ if len(frame_match.groups()) == 4:
+ (frame_id, frame_img_name, frame_addr,
+ frame_ofs) = frame_match.groups()
+ else:
+ (frame_id, frame_img_name, frame_addr,
+ frame_ofs, frame_symbol, frame_offset) = frame_match.groups()
thread.add_ident(frame_img_name)
if frame_img_name not in self.crashlog.idents:
@@ -641,11 +661,11 @@
thread_regex = re.compile(r'^Thread (\d+).*:')
app_backtrace_regex = re.compile(r'^Application Specific Backtrace (\d+).*:')
version = r'\(.+\)|(?:arm|x86_)[0-9a-z]+'
- frame_regex = re.compile(r'^(\d+)\s+' # id
- r'(.+?)\s+' # img_name
- r'(?:' +version+ r'\s+)?' # img_version
- r'(0x[0-9a-fA-F]{4,})' # addr (4 chars or more)
- r'(?: +(.*))?' # offs
+ frame_regex = re.compile(r'^(\d+)\s+' # id
+ r'(.+?)\s+' # img_name
+ r'(?:' +version+ r'\s+)?' # img_version
+ r'(0x[0-9a-fA-F]{4,}) +' # addr (4 chars or more)
+ r'((.*)(?:(?: +\+ +)([0-9]+))|[^\s]+)' # symbol + offset
)
null_frame_regex = re.compile(r'^\d+\s+\?\?\?\s+0{4,} +')
image_regex_uuid = re.compile(r'(0x[0-9a-fA-F]+)' # img_lo
@@ -828,12 +848,37 @@
return
frame_match = self.frame_regex.search(line)
if frame_match:
- (frame_id, frame_img_name, frame_addr,
- frame_ofs) = frame_match.groups()
+ if len(frame_match.groups()) == 4:
+ # Get the image UUID from the frame image name.
+ (frame_id, frame_img_name, frame_addr,
+ frame_ofs) = frame_match.groups()
+ else:
+ (frame_id, frame_img_name, frame_addr,
+ frame_ofs, frame_symbol, frame_offset) = frame_match.groups()
ident = frame_img_name
self.thread.add_ident(ident)
if ident not in self.crashlog.idents:
self.crashlog.idents.append(ident)
+
+ # Because of the Textual Crash Report layout, the thread section
+ # gets parsed before the binary images section. This means we can
+ # get the image's UUID and triple right away.
+ # This is why we need to do a second pass when parsing the binary
+ # images section to update these fields.
+ if not frame_ofs or int(frame_addr) != 0:
+ if frame_img_name not in self.symbol_data:
+ self.symbol_data[frame_img_name] = {
+ "symbols" : list(),
+ "uuid": uuid.UUID(int=0),
+ "triple": None
+ }
+ self.symbol_data[frame_img_name]['symbols'].append({
+ "name": frame_ofs,
+ "type": "code",
+ "size": 0,
+ "address": frame_addr,
+ })
+
self.thread.frames.append(self.crashlog.Frame(int(frame_id), int(
frame_addr, 0), frame_ofs))
else:
@@ -844,6 +889,11 @@
if image_match:
(img_lo, img_hi, img_name, img_version,
img_uuid, img_path) = image_match.groups()
+
+ # Now that we've parsed the image, we can update its symbol_data UUID
+ if img_name in self.symbol_data:
+ self.symbol_data[frame_img_name]['uuid'] = image_uuid
+
image = self.crashlog.DarwinImage(int(img_lo, 0), int(img_hi, 0),
img_name.strip(),
img_version.strip()
@@ -1076,7 +1126,8 @@
if not os.path.exists(crashlog_path):
raise InteractiveCrashLogException("crashlog file %s does not exist" % crashlog_path)
- crashlog = CrashLogParser.create(debugger, crashlog_path, False).parse()
+ crashlog_parser = CrashLogParser.create(debugger, crashlog_path, False)
+ crashlog = crashlog_parser.parse()
target = lldb.SBTarget()
# 1. Try to use the user-provided target
@@ -1116,6 +1167,36 @@
if not process or error.Fail():
raise InteractiveCrashLogException("couldn't launch Scripted Process", error)
+ tmp_dir = tempfile.TemporaryDirectory()
+ for image, symbol_data in crashlog_parser.symbol_data.items():
+ module_spec = lldb.SBModuleSpec()
+ if crashlog_parser.__class__ == JSONCrashLogParser:
+ u = uuid.UUID(image)
+ module_spec.SetUUIDFromString(u.hex)
+ else:
+ module_spec.SetObjectName(image)
+
+ if not symbol_data['triple']:
+ symbol_data["triple"] = target.GetModuleAtIndex(0).GetTriple()
+
+ symbol_uuid = symbol_data['uuid']
+ symbol_file = os.path.join(tmp_dir.name, symbol_uuid + ".json")
+ print(symbol_file)
+ with open(symbol_file, 'w') as f:
+ f.write(json.dumps(symbol_data))
+
+ ci.HandleCommand("target symbols add -s '%s' %s" %
+ (symbol_uuid, symbol_file), result)
+ if not result.Succeeded():
+ raise InteractiveCrashLogException("couldn't import crash report " +
+ "inlined symbols for module %s" %
+ symbol_uuid)
+
+ if os.path.exists(tmp_dir.name):
+ for file in os.listdir(tmp_dir.name):
+ os.unlink(file)
+ os.rmdir(tmp_dir.name)
+
if not options.skip_status:
@contextlib.contextmanager
def synchronous(debugger):
_______________________________________________
lldb-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits