[Lldb-commits] [lldb] 66f8819 - [lldb/crashlog] Refactor the CrashLogParser logic

Med Ismail Bennani via lldb-commits lldb-commits at lists.llvm.org
Tue Aug 9 21:02:12 PDT 2022


Author: Med Ismail Bennani
Date: 2022-08-09T21:01:37-07:00
New Revision: 66f8819c5087198a62ba15da4477d59b9e4a1a1d

URL: https://github.com/llvm/llvm-project/commit/66f8819c5087198a62ba15da4477d59b9e4a1a1d
DIFF: https://github.com/llvm/llvm-project/commit/66f8819c5087198a62ba15da4477d59b9e4a1a1d.diff

LOG: [lldb/crashlog] Refactor the CrashLogParser logic

This patch changes the CrashLogParser class to be both the base class
and a Factory for the JSONCrashLogParser & TextCrashLogParser.

That should help remove some code duplication and ensure both class
have a parse method.

Differential Revision: https://reviews.llvm.org/D131085

Signed-off-by: Med Ismail Bennani <medismail.bennani at gmail.com>

Added: 
    

Modified: 
    lldb/examples/python/crashlog.py
    lldb/examples/python/scripted_process/crashlog_scripted_process.py

Removed: 
    


################################################################################
diff  --git a/lldb/examples/python/crashlog.py b/lldb/examples/python/crashlog.py
index 56cdd09c5658..4773a136bfae 100755
--- a/lldb/examples/python/crashlog.py
+++ b/lldb/examples/python/crashlog.py
@@ -26,6 +26,7 @@
 #   PYTHONPATH=/path/to/LLDB.framework/Resources/Python ./crashlog.py ~/Library/Logs/DiagnosticReports/a.crash
 #----------------------------------------------------------------------
 
+import abc
 import concurrent.futures
 import contextlib
 import datetime
@@ -415,37 +416,46 @@ class InteractiveCrashLogException(Exception):
     pass
 
 class CrashLogParser:
-    def parse(self, debugger, path, verbose):
-        try:
-            return JSONCrashLogParser(debugger, path, verbose).parse()
-        except CrashLogFormatException:
-            return TextCrashLogParser(debugger, path, verbose).parse()
-
+    "CrashLog parser base class and factory."
+    def __new__(cls, debugger, path, verbose):
+        data = JSONCrashLogParser.is_valid_json(path)
+        if data:
+            self = object.__new__(JSONCrashLogParser)
+            self.data = data
+            return self
+        else:
+            return object.__new__(TextCrashLogParser)
 
-class JSONCrashLogParser:
     def __init__(self, debugger, path, verbose):
         self.path = os.path.expanduser(path)
         self.verbose = verbose
         self.crashlog = CrashLog(debugger, self.path, self.verbose)
 
-    def parse_json(self, buffer):
-        try:
-            return json.loads(buffer)
-        except:
-            # The first line can contain meta data. Try stripping it and try
-            # again.
-            head, _, tail = buffer.partition('\n')
-            return json.loads(tail)
-
+    @abc.abstractmethod
     def parse(self):
-        with open(self.path, 'r') as f:
-            buffer = f.read()
+        pass
+
 
+class JSONCrashLogParser(CrashLogParser):
+    @staticmethod
+    def is_valid_json(path):
+        def parse_json(buffer):
+            try:
+                return json.loads(buffer)
+            except:
+                # The first line can contain meta data. Try stripping it and
+                # try again.
+                head, _, tail = buffer.partition('\n')
+                return json.loads(tail)
+
+        with open(path, 'r') as f:
+            buffer = f.read()
         try:
-            self.data = self.parse_json(buffer)
+            return parse_json(buffer)
         except:
-            raise CrashLogFormatException()
+            return None
 
+    def parse(self):
         try:
             self.parse_process_info(self.data)
             self.parse_images(self.data['usedImages'])
@@ -592,7 +602,7 @@ class CrashLogParseMode:
     INSTRS = 5
 
 
-class TextCrashLogParser:
+class TextCrashLogParser(CrashLogParser):
     parent_process_regex = re.compile('^Parent Process:\s*(.*)\[(\d+)\]')
     thread_state_regex = re.compile('^Thread ([0-9]+) crashed with')
     thread_instrs_regex = re.compile('^Thread ([0-9]+) instruction stream')
@@ -615,13 +625,10 @@ class TextCrashLogParser:
                                   r'(/.*)'                       # img_path
                                  )
 
-
     def __init__(self, debugger, path, verbose):
-        self.path = os.path.expanduser(path)
-        self.verbose = verbose
+        super().__init__(debugger, path, verbose)
         self.thread = None
         self.app_specific_backtrace = False
-        self.crashlog = CrashLog(debugger, self.path, self.verbose)
         self.parse_mode = CrashLogParseMode.NORMAL
         self.parsers = {
             CrashLogParseMode.NORMAL : self.parse_normal,
@@ -1012,7 +1019,7 @@ def load_crashlog_in_scripted_process(debugger, crash_log_file, options, result)
     if not os.path.exists(crashlog_path):
         raise InteractiveCrashLogException("crashlog file %s does not exist" % crashlog_path)
 
-    crashlog = CrashLogParser().parse(debugger, crashlog_path, False)
+    crashlog = CrashLogParser(debugger, crashlog_path, False).parse()
 
     target = lldb.SBTarget()
     # 1. Try to use the user-provided target
@@ -1257,7 +1264,7 @@ def should_run_in_interactive_mode(options, ci):
                 except InteractiveCrashLogException as e:
                     result.SetError(str(e))
             else:
-                crash_log = CrashLogParser().parse(debugger, crash_log_file, options.verbose)
+                crash_log = CrashLogParser(debugger, crash_log_file, options.verbose).parse()
                 SymbolicateCrashLog(crash_log, options)
 
 if __name__ == '__main__':

diff  --git a/lldb/examples/python/scripted_process/crashlog_scripted_process.py b/lldb/examples/python/scripted_process/crashlog_scripted_process.py
index 3a5b175dce86..ffdd43d7c5d8 100644
--- a/lldb/examples/python/scripted_process/crashlog_scripted_process.py
+++ b/lldb/examples/python/scripted_process/crashlog_scripted_process.py
@@ -10,10 +10,8 @@
 
 class CrashLogScriptedProcess(ScriptedProcess):
     def parse_crashlog(self):
-        try:
-            crash_log = CrashLogParser().parse(self.dbg, self.crashlog_path, False)
-        except Exception as e:
-            raise e
+        crashlog_parser = CrashLogParser(self.dbg, self.crashlog_path, False)
+        crash_log = crashlog_parser.parse()
 
         self.pid = crash_log.process_id
         self.addr_mask = crash_log.addr_mask


        


More information about the lldb-commits mailing list