summaryrefslogtreecommitdiff
path: root/lldb/examples
diff options
context:
space:
mode:
authorMed Ismail Bennani <medismail.bennani@gmail.com>2022-08-11 18:07:20 -0700
committerMed Ismail Bennani <medismail.bennani@gmail.com>2022-08-11 22:29:06 -0700
commit300e393092e39c8efc76f807671b11309fb4b98e (patch)
treebf313f9934c19b5ea54d8c9caa08fbc38780e739 /lldb/examples
parent4a738ee8220e02df62b7b43d3fe5b2d6be88c482 (diff)
downloadllvm-300e393092e39c8efc76f807671b11309fb4b98e.tar.gz
[lldb/crashlog] Adapt raw text crashlog exception to json format
This patch parses CrashLog exception data from the raw text format and adapts it to the new JSON format. This is necessary for feature parity between the 2 formats. Differential Revision: https://reviews.llvm.org/D131719 Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
Diffstat (limited to 'lldb/examples')
-rwxr-xr-xlldb/examples/python/crashlog.py51
1 files changed, 40 insertions, 11 deletions
diff --git a/lldb/examples/python/crashlog.py b/lldb/examples/python/crashlog.py
index ad0d70a669a8..eb43e07d27f4 100755
--- a/lldb/examples/python/crashlog.py
+++ b/lldb/examples/python/crashlog.py
@@ -340,6 +340,7 @@ class CrashLog(symbolication.Symbolicator):
self.backtraces = list() # For application specific backtraces
self.idents = list() # A list of the required identifiers for doing all stack backtraces
self.errors = list()
+ self.exception = dict()
self.crashed_thread_idx = -1
self.version = -1
self.target = None
@@ -483,6 +484,7 @@ class JSONCrashLogParser(CrashLogParser):
self.crashlog.process_identifier = json_data['procName']
def parse_crash_reason(self, json_exception):
+ self.crashlog.exception = json_exception
exception_type = json_exception['type']
exception_signal = " "
if 'signal' in json_exception:
@@ -601,7 +603,6 @@ class CrashLogParseMode:
SYSTEM = 4
INSTRS = 5
-
class TextCrashLogParser(CrashLogParser):
parent_process_regex = re.compile(r'^Parent Process:\s*(.*)\[(\d+)\]')
thread_state_regex = re.compile(r'^Thread \d+ crashed with')
@@ -624,6 +625,9 @@ class TextCrashLogParser(CrashLogParser):
r'(?:<([-0-9a-fA-F]+)>\s+)?' # img_uuid
r'(/.*)' # img_path
)
+ exception_type_regex = re.compile(r'^Exception Type:\s+(EXC_[A-Z_]+)(?:\s+\((.*)\))?')
+ exception_codes_regex = re.compile(r'^Exception Codes:\s+(0x[0-9a-fA-F]+),\s*(0x[0-9a-fA-F]+)')
+ exception_extra_regex = re.compile(r'^Exception\s+.*:\s+(.*)')
def __init__(self, debugger, path, verbose):
super().__init__(debugger, path, verbose)
@@ -650,9 +654,9 @@ class TextCrashLogParser(CrashLogParser):
if self.parse_mode == CrashLogParseMode.THREAD:
if self.thread.index == self.crashlog.crashed_thread_idx:
self.thread.reason = ''
- if self.crashlog.thread_exception:
+ if hasattr(self.crashlog, 'thread_exception'):
self.thread.reason += self.crashlog.thread_exception
- if self.crashlog.thread_exception_data:
+ if hasattr(self.crashlog, 'thread_exception_data'):
self.thread.reason += " (%s)" % self.crashlog.thread_exception_data
if self.app_specific_backtrace:
self.crashlog.backtraces.append(self.thread)
@@ -670,6 +674,37 @@ class TextCrashLogParser(CrashLogParser):
return self.crashlog
+ def parse_exception(self, line):
+ if not line.startswith('Exception'):
+ return
+ if line.startswith('Exception Type:'):
+ self.crashlog.thread_exception = line[15:].strip()
+ exception_type_match = self.exception_type_regex.search(line)
+ if exception_type_match:
+ exc_type, exc_signal = exception_type_match.groups()
+ self.crashlog.exception['type'] = exc_type
+ if exc_signal:
+ self.crashlog.exception['signal'] = exc_signal
+ elif line.startswith('Exception Subtype:'):
+ self.crashlog.thread_exception_subtype = line[18:].strip()
+ if 'type' in self.crashlog.exception:
+ self.crashlog.exception['subtype'] = self.crashlog.thread_exception_subtype
+ elif line.startswith('Exception Codes:'):
+ self.crashlog.thread_exception_data = line[16:].strip()
+ if 'type' not in self.crashlog.exception:
+ return
+ exception_codes_match = self.exception_codes_regex.search(line)
+ if exception_codes_match:
+ self.crashlog.exception['codes'] = self.crashlog.thread_exception_data
+ code, subcode = exception_codes_match.groups()
+ self.crashlog.exception['rawCodes'] = [int(code, base=16),
+ int(subcode, base=16)]
+ else:
+ if 'type' not in self.crashlog.exception:
+ return
+ exception_extra_match = self.exception_extra_regex.search(line)
+ if exception_extra_match:
+ self.crashlog.exception['message'] = exception_extra_match.group(1)
def parse_normal(self, line):
if line.startswith('Process:'):
@@ -693,14 +728,8 @@ class TextCrashLogParser(CrashLogParser):
line)
self.crashlog.parent_process_name = parent_process_match.group(1)
self.crashlog.parent_process_id = parent_process_match.group(2)
- elif line.startswith('Exception Type:'):
- self.crashlog.thread_exception = line[15:].strip()
- return
- elif line.startswith('Exception Codes:'):
- self.crashlog.thread_exception_data = line[16:].strip()
- return
- elif line.startswith('Exception Subtype:'): # iOS
- self.crashlog.thread_exception_data = line[18:].strip()
+ elif line.startswith('Exception'):
+ self.parse_exception(line)
return
elif line.startswith('Crashed Thread:'):
self.crashlog.crashed_thread_idx = int(line[15:].strip().split()[0])