[lldb/crashlog] Refactor CrashLogParser into a Factory pattern
authorMed Ismail Bennani <medismail.bennani@gmail.com>
Thu, 12 Jan 2023 23:26:49 +0000 (15:26 -0800)
committerMed Ismail Bennani <medismail.bennani@gmail.com>
Fri, 13 Jan 2023 03:20:51 +0000 (19:20 -0800)
This patch should fix an undefined behaviour that's happening when
parsing a crash report from an IDE. In the previous implementation, the
CrashLogParser base class would use the `__new__` static class method to
create the right parser instance depending on the crash report type.

For some reasons, the derived parser initializer wouldn't be called when
running the command from an IDE, so this patch refactors the
CrashLogParser code to replace the use of the `__new__` method with a
factory `create` static method.

rdar://100527640

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

Signed-off-by: Med Ismail Bennani <medismail.bennani@gmail.com>
lldb/examples/python/crashlog.py
lldb/examples/python/scripted_process/crashlog_scripted_process.py

index b62ebd7..d9e0370 100755 (executable)
@@ -417,15 +417,15 @@ class InteractiveCrashLogException(Exception):
     pass
 
 class CrashLogParser:
-    "CrashLog parser base class and factory."
-    def __new__(cls, debugger, path, verbose):
+    @staticmethod
+    def create(debugger, path, verbose):
         data = JSONCrashLogParser.is_valid_json(path)
         if data:
-            self = object.__new__(JSONCrashLogParser)
-            self.data = data
-            return self
+            parser = JSONCrashLogParser(debugger, path, verbose)
+            parser.data = data
+            return parser
         else:
-            return object.__new__(TextCrashLogParser)
+            return TextCrashLogParser(debugger, path, verbose)
 
     def __init__(self, debugger, path, verbose):
         self.path = os.path.expanduser(path)
@@ -1076,7 +1076,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(debugger, crashlog_path, False).parse()
+    crashlog = CrashLogParser.create(debugger, crashlog_path, False).parse()
 
     target = lldb.SBTarget()
     # 1. Try to use the user-provided target
@@ -1332,7 +1332,7 @@ def SymbolicateCrashLogs(debugger, command_args, result):
                 except InteractiveCrashLogException as e:
                     result.SetError(str(e))
             else:
-                crash_log = CrashLogParser(debugger, crash_log_file, options.verbose).parse()
+                crash_log = CrashLogParser.create(debugger, crash_log_file, options.verbose).parse()
                 SymbolicateCrashLog(crash_log, options)
 
 if __name__ == '__main__':
index eddf967..dfb32aa 100644 (file)
@@ -10,7 +10,7 @@ from lldb.macosx.crashlog import CrashLog,CrashLogParser
 
 class CrashLogScriptedProcess(ScriptedProcess):
     def parse_crashlog(self):
-        crashlog_parser = CrashLogParser(self.dbg, self.crashlog_path, False)
+        crashlog_parser = CrashLogParser.create(self.dbg, self.crashlog_path, False)
         crash_log = crashlog_parser.parse()
 
         self.pid = crash_log.process_id