[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>
This commit is contained in:
Med Ismail Bennani 2022-08-11 18:07:20 -07:00
parent 4a738ee822
commit 300e393092
1 changed files with 40 additions and 11 deletions

View File

@ -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])