aboutsummaryrefslogtreecommitdiff
path: root/lldb/examples/python/crashlog.py
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/examples/python/crashlog.py')
-rwxr-xr-xlldb/examples/python/crashlog.py91
1 files changed, 60 insertions, 31 deletions
diff --git a/lldb/examples/python/crashlog.py b/lldb/examples/python/crashlog.py
index ccf3fb1..7f1a43b 100755
--- a/lldb/examples/python/crashlog.py
+++ b/lldb/examples/python/crashlog.py
@@ -537,21 +537,21 @@ class InteractiveCrashLogException(Exception):
class CrashLogParser:
@staticmethod
- def create(debugger, path, verbose):
+ def create(debugger, path, options):
data = JSONCrashLogParser.is_valid_json(path)
if data:
- parser = JSONCrashLogParser(debugger, path, verbose)
+ parser = JSONCrashLogParser(debugger, path, options)
parser.data = data
return parser
else:
- return TextCrashLogParser(debugger, path, verbose)
+ return TextCrashLogParser(debugger, path, options)
- def __init__(self, debugger, path, verbose):
+ def __init__(self, debugger, path, options):
self.path = os.path.expanduser(path)
- self.verbose = verbose
+ self.options = options
# List of DarwinImages sorted by their index.
self.images = list()
- self.crashlog = CrashLog(debugger, self.path, self.verbose)
+ self.crashlog = CrashLog(debugger, self.path, self.options.verbose)
@abc.abstractmethod
def parse(self):
@@ -577,8 +577,8 @@ class JSONCrashLogParser(CrashLogParser):
except:
return None
- def __init__(self, debugger, path, verbose):
- super().__init__(debugger, path, verbose)
+ def __init__(self, debugger, path, options):
+ super().__init__(debugger, path, options)
def parse(self):
try:
@@ -639,7 +639,7 @@ class JSONCrashLogParser(CrashLogParser):
path = json_image["path"] if "path" in json_image else ""
version = ""
darwin_image = self.crashlog.DarwinImage(
- low, high, name, version, img_uuid, path, self.verbose
+ low, high, name, version, img_uuid, path, self.options.verbose
)
if "arch" in json_image:
darwin_image.arch = json_image["arch"]
@@ -898,8 +898,8 @@ class TextCrashLogParser(CrashLogParser):
)
exception_extra_regex = re.compile(r"^Exception\s+.*:\s+(.*)")
- def __init__(self, debugger, path, verbose):
- super().__init__(debugger, path, verbose)
+ def __init__(self, debugger, path, options):
+ super().__init__(debugger, path, options)
self.thread = None
self.app_specific_backtrace = False
self.parse_mode = CrashLogParseMode.NORMAL
@@ -917,8 +917,15 @@ class TextCrashLogParser(CrashLogParser):
with open(self.path, "r", encoding="utf-8") as f:
lines = f.read().splitlines()
- for line in lines:
+ idx = 0
+ lines_count = len(lines)
+ while True:
+ if idx >= lines_count:
+ break
+
+ line = lines[idx]
line_len = len(line)
+
if line_len == 0:
if self.thread:
if self.parse_mode == CrashLogParseMode.THREAD:
@@ -935,22 +942,36 @@ class TextCrashLogParser(CrashLogParser):
else:
self.crashlog.threads.append(self.thread)
self.thread = None
- else:
- # only append an extra empty line if the previous line
- # in the info_lines wasn't empty
- if len(self.crashlog.info_lines) > 0 and len(
- self.crashlog.info_lines[-1]
- ):
- self.crashlog.info_lines.append(line)
+
+ empty_lines = 1
+ while (
+ idx + empty_lines < lines_count
+ and len(lines[idx + empty_lines]) == 0
+ ):
+ empty_lines = empty_lines + 1
+
+ if (
+ empty_lines == 1
+ and idx + empty_lines < lines_count - 1
+ and self.parse_mode != CrashLogParseMode.NORMAL
+ ):
+ # check if next line can be parsed with the current parse mode
+ next_line_idx = idx + empty_lines
+ if self.parsers[self.parse_mode](lines[next_line_idx]):
+ # If that suceeded, skip the empty line and the next line.
+ idx = next_line_idx + 1
+ continue
self.parse_mode = CrashLogParseMode.NORMAL
- else:
- self.parsers[self.parse_mode](line)
+
+ self.parsers[self.parse_mode](line)
+
+ idx = idx + 1
return self.crashlog
def parse_exception(self, line):
if not line.startswith("Exception"):
- return
+ return False
if line.startswith("Exception Type:"):
self.crashlog.thread_exception = line[15:].strip()
exception_type_match = self.exception_type_regex.search(line)
@@ -968,7 +989,7 @@ class TextCrashLogParser(CrashLogParser):
elif line.startswith("Exception Codes:"):
self.crashlog.thread_exception_data = line[16:].strip()
if "type" not in self.crashlog.exception:
- return
+ return False
exception_codes_match = self.exception_codes_regex.search(line)
if exception_codes_match:
self.crashlog.exception["codes"] = self.crashlog.thread_exception_data
@@ -979,10 +1000,11 @@ class TextCrashLogParser(CrashLogParser):
]
else:
if "type" not in self.crashlog.exception:
- return
+ return False
exception_extra_match = self.exception_extra_regex.search(line)
if exception_extra_match:
self.crashlog.exception["message"] = exception_extra_match.group(1)
+ return True
def parse_normal(self, line):
if line.startswith("Process:"):
@@ -1081,14 +1103,14 @@ class TextCrashLogParser(CrashLogParser):
def parse_thread(self, line):
if line.startswith("Thread"):
- return
+ return False
if self.null_frame_regex.search(line):
print('warning: thread parser ignored null-frame: "%s"' % line)
- return
+ return False
frame_match = self.frame_regex.search(line)
if not frame_match:
print('error: frame regex failed for line: "%s"' % line)
- return
+ return False
frame_id = (
frame_img_name
@@ -1155,6 +1177,8 @@ class TextCrashLogParser(CrashLogParser):
self.crashlog.Frame(int(frame_id), int(frame_addr, 0), description)
)
+ return True
+
def parse_images(self, line):
image_match = self.image_regex_uuid.search(line)
if image_match:
@@ -1174,7 +1198,7 @@ class TextCrashLogParser(CrashLogParser):
img_version.strip() if img_version else "",
uuid.UUID(img_uuid),
img_path,
- self.verbose,
+ self.options.verbose,
)
unqualified_img_name = os.path.basename(img_path)
if unqualified_img_name in self.symbols:
@@ -1188,17 +1212,22 @@ class TextCrashLogParser(CrashLogParser):
self.images.append(image)
self.crashlog.images.append(image)
+ return True
else:
- print("error: image regex failed for: %s" % line)
+ if self.options.debug:
+ print("error: image regex failed for: %s" % line)
+ return False
def parse_thread_registers(self, line):
# "r12: 0x00007fff6b5939c8 r13: 0x0000000007000006 r14: 0x0000000000002a03 r15: 0x0000000000000c00"
reg_values = re.findall("([a-z0-9]+): (0x[0-9a-f]+)", line, re.I)
for reg, value in reg_values:
self.thread.registers[reg] = int(value, 16)
+ return len(reg_values) != 0
def parse_system(self, line):
self.crashlog.system_profile.append(line)
+ return True
def parse_instructions(self, line):
pass
@@ -1412,7 +1441,7 @@ def SymbolicateCrashLog(crash_log, options):
def load_crashlog_in_scripted_process(debugger, crashlog_path, options, result):
- crashlog = CrashLogParser.create(debugger, crashlog_path, False).parse()
+ crashlog = CrashLogParser.create(debugger, crashlog_path, options).parse()
target = lldb.SBTarget()
# 1. Try to use the user-provided target
@@ -1735,7 +1764,7 @@ def SymbolicateCrashLogs(debugger, command_args, result, is_command):
result.SetError(str(e))
else:
crash_log = CrashLogParser.create(
- debugger, crashlog_path, options.verbose
+ debugger, crashlog_path, options
).parse()
SymbolicateCrashLog(crash_log, options)