[Lldb-commits] [lldb] 78d6e1d - [lldb/crashlog] Add support for Application Specific Backtraces & Information

Med Ismail Bennani via lldb-commits lldb-commits at lists.llvm.org
Thu Nov 3 14:45:27 PDT 2022


Author: Med Ismail Bennani
Date: 2022-11-03T14:44:53-07:00
New Revision: 78d6e1d1d4b3b5c6bdd779256c915a8ac7148174

URL: https://github.com/llvm/llvm-project/commit/78d6e1d1d4b3b5c6bdd779256c915a8ac7148174
DIFF: https://github.com/llvm/llvm-project/commit/78d6e1d1d4b3b5c6bdd779256c915a8ac7148174.diff

LOG: [lldb/crashlog] Add support for Application Specific Backtraces & Information

For an exception crashlog, the thread backtraces aren't usually very helpful
and instead, developpers look at the "Application Specific Backtrace" that
was generated by `objc_exception_throw`.

LLDB could already parse and symbolicate these Application Specific Backtraces
for regular textual-based crashlog, so this patch adds support to parse them
in JSON crashlogs, and materialize them a HistoryThread extending the
crashed ScriptedThread.

This patch also includes the Application Specific Information messages
as part of the process extended crash information log. To do so, the
ScriptedProcess Python interface has a new GetMetadata method that
returns an arbitrary dictionary with data related to the process.

rdar://93207586

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

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

Added: 
    lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.ips
    lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.yaml
    lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/main.m
    lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test

Modified: 
    lldb/examples/python/crashlog.py
    lldb/examples/python/scripted_process/crashlog_scripted_process.py
    lldb/examples/python/scripted_process/scripted_process.py
    lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
    lldb/include/lldb/Target/Process.h
    lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
    lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
    lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
    lldb/source/Plugins/Process/scripted/ScriptedProcess.h
    lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
    lldb/source/Plugins/Process/scripted/ScriptedThread.h
    lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
    lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
    lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
    lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
    lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
    lldb/test/API/functionalities/process_crash_info/TestProcessCrashInfo.py

Removed: 
    


################################################################################
diff  --git a/lldb/examples/python/crashlog.py b/lldb/examples/python/crashlog.py
index 8aaf7c165684a..47250f3b350f1 100755
--- a/lldb/examples/python/crashlog.py
+++ b/lldb/examples/python/crashlog.py
@@ -462,6 +462,12 @@ def parse(self):
             self.parse_images(self.data['usedImages'])
             self.parse_main_image(self.data)
             self.parse_threads(self.data['threads'])
+            if 'asi' in self.data:
+                self.crashlog.asi = self.data['asi']
+            if 'asiBacktraces' in self.data:
+                self.parse_app_specific_backtraces(self.data['asiBacktraces'])
+            if 'lastExceptionBacktrace' in self.data:
+                self.crashlog.asb = self.data['lastExceptionBacktrace']
             self.parse_errors(self.data)
             thread = self.crashlog.threads[self.crashlog.crashed_thread_idx]
             reason = self.parse_crash_reason(self.data['exception'])
@@ -573,6 +579,31 @@ def parse_threads(self, json_threads):
             self.crashlog.threads.append(thread)
             idx += 1
 
+    def parse_asi_backtrace(self, thread, bt):
+        for line in bt.split('\n'):
+            frame_match = TextCrashLogParser.frame_regex.search(line)
+            if not frame_match:
+                print("error: can't parse application specific backtrace.")
+                return False
+
+            (frame_id, frame_img_name, frame_addr,
+                frame_ofs) = frame_match.groups()
+
+            thread.add_ident(frame_img_name)
+            if frame_img_name not in self.crashlog.idents:
+                self.crashlog.idents.append(frame_img_name)
+            thread.frames.append(self.crashlog.Frame(int(frame_id), int(
+                frame_addr, 0), frame_ofs))
+
+        return True
+
+    def parse_app_specific_backtraces(self, json_app_specific_bts):
+        for idx, backtrace in enumerate(json_app_specific_bts):
+            thread = self.crashlog.Thread(idx, True)
+            thread.queue = "Application Specific Backtrace"
+            if self.parse_asi_backtrace(thread, backtrace):
+                self.crashlog.threads.append(thread)
+
     def parse_thread_registers(self, json_thread_state, prefix=None):
         registers = dict()
         for key, state in json_thread_state.items():
@@ -1102,8 +1133,8 @@ def synchronous(debugger):
             run_options.SetEchoCommands(True)
 
             commands_stream = lldb.SBStream()
-            commands_stream.Print("process status\n")
-            commands_stream.Print("thread backtrace\n")
+            commands_stream.Print("process status --verbose\n")
+            commands_stream.Print("thread backtrace --extended true\n")
             error = debugger.SetInputString(commands_stream.GetData())
             if error.Success():
                 debugger.RunCommandInterpreter(True, False, run_options, 0, False, True)

diff  --git a/lldb/examples/python/scripted_process/crashlog_scripted_process.py b/lldb/examples/python/scripted_process/crashlog_scripted_process.py
index e64b9b7822af1..55c50917c9d67 100644
--- a/lldb/examples/python/scripted_process/crashlog_scripted_process.py
+++ b/lldb/examples/python/scripted_process/crashlog_scripted_process.py
@@ -18,6 +18,11 @@ def parse_crashlog(self):
         self.crashed_thread_idx = crash_log.crashed_thread_idx
         self.loaded_images = []
         self.exception = crash_log.exception
+        self.app_specific_thread = None
+        if hasattr(crash_log, 'asi'):
+            self.metadata['asi'] = crash_log.asi
+        if hasattr(crash_log, 'asb'):
+            self.extended_thread_info = crash_log.asb
 
         def load_images(self, images):
             #TODO: Add to self.loaded_images and load images in lldb
@@ -40,8 +45,23 @@ def load_images(self, images):
                 for ident in thread.idents:
                     load_images(self, crash_log.find_images_with_identifier(ident))
 
+            if hasattr(thread, 'app_specific_backtrace') and thread.app_specific_backtrace:
+                # We don't want to include the Application Specific Backtrace
+                # Thread into the Scripted Process' Thread list.
+                # Instead, we will try to extract the stackframe pcs from the
+                # backtrace and inject that as the extended thread info.
+                self.app_specific_thread = thread
+                continue
+
             self.threads[thread.index] = CrashLogScriptedThread(self, None, thread)
 
+
+        if self.app_specific_thread:
+            self.extended_thread_info = \
+                    CrashLogScriptedThread.resolve_stackframes(self.app_specific_thread,
+                                                               self.addr_mask,
+                                                               self.target)
+
     def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData):
         super().__init__(target, args)
 
@@ -71,6 +91,7 @@ def __init__(self, target: lldb.SBTarget, args : lldb.SBStructuredData):
         self.pid = super().get_process_id()
         self.crashed_thread_idx = 0
         self.exception = None
+        self.extended_thread_info = None
         self.parse_crashlog()
 
     def get_memory_region_containing_address(self, addr: int) -> lldb.SBMemoryRegionInfo:
@@ -103,6 +124,9 @@ def is_alive(self) -> bool:
     def get_scripted_thread_plugin(self):
         return CrashLogScriptedThread.__module__ + "." + CrashLogScriptedThread.__name__
 
+    def get_process_metadata(self):
+        return self.metadata
+
 class CrashLogScriptedThread(ScriptedThread):
     def create_register_ctx(self):
         if not self.has_crashed:
@@ -120,6 +144,19 @@ def create_register_ctx(self):
 
         return self.register_ctx
 
+    def resolve_stackframes(thread, addr_mask, target):
+        frames = []
+        for frame in thread.frames:
+            frame_pc = frame.pc & addr_mask
+            pc = frame_pc if frame.index == 0  or frame_pc == 0 else frame_pc - 1
+            sym_addr = lldb.SBAddress()
+            sym_addr.SetLoadAddress(pc, target)
+            if not sym_addr.IsValid():
+                continue
+            frames.append({"idx": frame.index, "pc": pc})
+        return frames
+
+
     def create_stackframes(self):
         if not (self.scripted_process.load_all_images or self.has_crashed):
             return None
@@ -127,14 +164,9 @@ def create_stackframes(self):
         if not self.backing_thread or not len(self.backing_thread.frames):
             return None
 
-        for frame in self.backing_thread.frames:
-            frame_pc = frame.pc & self.scripted_process.addr_mask
-            pc = frame_pc if frame.index == 0  or frame_pc == 0 else frame_pc - 1
-            sym_addr = lldb.SBAddress()
-            sym_addr.SetLoadAddress(pc, self.target)
-            if not sym_addr.IsValid():
-                continue
-            self.frames.append({"idx": frame.index, "pc": pc})
+        self.frames = CrashLogScriptedThread.resolve_stackframes(self.backing_thread,
+                                                                 self.scripted_process.addr_mask,
+                                                                 self.target)
 
         return self.frames
 
@@ -144,7 +176,10 @@ def __init__(self, process, args, crashlog_thread):
         self.backing_thread = crashlog_thread
         self.idx = self.backing_thread.index
         self.tid = self.backing_thread.id
-        self.name = self.backing_thread.name
+        if self.backing_thread.app_specific_backtrace:
+            self.name = "Application Specific Backtrace - " + str(self.idx)
+        else:
+            self.name = self.backing_thread.name
         self.queue = self.backing_thread.queue
         self.has_crashed = (self.scripted_process.crashed_thread_idx == self.idx)
         self.create_stackframes()
@@ -168,3 +203,9 @@ def get_register_context(self) -> str:
             self.register_ctx = self.create_register_ctx()
 
         return struct.pack("{}Q".format(len(self.register_ctx)), *self.register_ctx.values())
+
+    def get_extended_info(self):
+        if (self.has_crashed):
+            self.extended_info = self.scripted_process.extended_thread_info
+        return self.extended_info
+

diff  --git a/lldb/examples/python/scripted_process/scripted_process.py b/lldb/examples/python/scripted_process/scripted_process.py
index 48966f8385cb0..43eb97dbd7723 100644
--- a/lldb/examples/python/scripted_process/scripted_process.py
+++ b/lldb/examples/python/scripted_process/scripted_process.py
@@ -18,6 +18,7 @@ class ScriptedProcess(metaclass=ABCMeta):
     stack_memory_dump = None
     loaded_images = None
     threads = None
+    metadata = None
 
     @abstractmethod
     def __init__(self, target, args):
@@ -41,6 +42,7 @@ def __init__(self, target, args):
             self.args = args
         self.threads = {}
         self.loaded_images = []
+        self.metadata = {}
 
     @abstractmethod
     def get_memory_region_containing_address(self, addr):
@@ -138,7 +140,6 @@ def get_process_id(self):
         """
         return 0
 
-
     def launch(self):
         """ Simulate the scripted process launch.
 
@@ -191,6 +192,15 @@ def get_scripted_thread_plugin(self):
         """
         return None
 
+    def get_process_metadata(self):
+        """ Get some metadata for the scripted process.
+
+        Returns:
+            Dict: A dictionary containing metadata for the scripted process.
+                  None is the process as no metadata.
+        """
+        return self.metadata
+
 class ScriptedThread(metaclass=ABCMeta):
 
     """
@@ -226,6 +236,7 @@ def __init__(self, scripted_process, args):
         self.register_info = None
         self.register_ctx = {}
         self.frames = []
+        self.extended_info = []
 
         if isinstance(scripted_process, ScriptedProcess):
             self.target = scripted_process.target
@@ -334,6 +345,15 @@ def get_register_context(self):
         """
         pass
 
+    def get_extended_info(self):
+        """ Get scripted thread extended information.
+
+        Returns:
+            List: A list containing the extended information for the scripted process.
+                  None is the thread as no extended information.
+        """
+        return self.extended_info
+
 ARM64_GPR = [ {'name': 'x0',   'bitsize': 64, 'offset': 0,   'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 0,  'dwarf': 0,  'generic': 'arg0', 'alt-name': 'arg0'},
               {'name': 'x1',   'bitsize': 64, 'offset': 8,   'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 1,  'dwarf': 1,  'generic': 'arg1', 'alt-name': 'arg1'},
               {'name': 'x2',   'bitsize': 64, 'offset': 16,  'encoding': 'uint', 'format': 'hex', 'set': 0, 'gcc': 2,  'dwarf': 2,  'generic': 'arg2', 'alt-name': 'arg2'},

diff  --git a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
index 905623e575f71..164ec9b9dd605 100644
--- a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
+++ b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
@@ -66,6 +66,8 @@ class ScriptedProcessInterface : virtual public ScriptedInterface {
     return llvm::None;
   }
 
+  virtual StructuredData::DictionarySP GetMetadata() { return nullptr; }
+
 protected:
   friend class ScriptedThread;
   virtual lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() {
@@ -99,6 +101,8 @@ class ScriptedThreadInterface : virtual public ScriptedInterface {
   virtual llvm::Optional<std::string> GetRegisterContext() {
     return llvm::None;
   }
+
+  virtual StructuredData::ArraySP GetExtendedInfo() { return nullptr; }
 };
 } // namespace lldb_private
 

diff  --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index 6975eb8029de0..b9995c2a44326 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2423,6 +2423,13 @@ void PruneThreadPlans();
     return Status("Not supported");
   }
 
+  /// Fetch process defined metadata.
+  ///
+  /// \return
+  ///     A StructuredDataSP object which, if non-empty, will contain the
+  ///     information related to the process.
+  virtual StructuredData::DictionarySP GetMetadata() { return nullptr; }
+
   size_t AddImageToken(lldb::addr_t image_ptr);
 
   lldb::addr_t GetImagePtrFromToken(size_t token) const;

diff  --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 21b733a62bbbb..9d89148616be1 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -857,21 +857,20 @@ PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
 
 llvm::Expected<StructuredData::DictionarySP>
 PlatformDarwin::FetchExtendedCrashInformation(Process &process) {
-  Log *log = GetLog(LLDBLog::Process);
-
-  StructuredData::ArraySP annotations = ExtractCrashInfoAnnotations(process);
-
-  if (!annotations || !annotations->GetSize()) {
-    LLDB_LOG(log, "Couldn't extract crash information annotations");
-    return nullptr;
-  }
-
   StructuredData::DictionarySP extended_crash_info =
       std::make_shared<StructuredData::Dictionary>();
 
-  extended_crash_info->AddItem("crash-info annotations", annotations);
+  StructuredData::ArraySP annotations = ExtractCrashInfoAnnotations(process);
+  if (annotations && annotations->GetSize())
+    extended_crash_info->AddItem("Crash-Info Annotations", annotations);
+
+  StructuredData::DictionarySP app_specific_info =
+      ExtractAppSpecificInfo(process);
+  if (app_specific_info && app_specific_info->GetSize())
+    extended_crash_info->AddItem("Application Specific Information",
+                                 app_specific_info);
 
-  return extended_crash_info;
+  return extended_crash_info->GetSize() ? extended_crash_info : nullptr;
 }
 
 StructuredData::ArraySP
@@ -978,6 +977,38 @@ PlatformDarwin::ExtractCrashInfoAnnotations(Process &process) {
   return array_sp;
 }
 
+StructuredData::DictionarySP
+PlatformDarwin::ExtractAppSpecificInfo(Process &process) {
+  StructuredData::DictionarySP metadata_sp = process.GetMetadata();
+
+  if (!metadata_sp || !metadata_sp->GetSize() || !metadata_sp->HasKey("asi"))
+    return {};
+
+  StructuredData::Dictionary *asi;
+  if (!metadata_sp->GetValueForKeyAsDictionary("asi", asi))
+    return {};
+
+  StructuredData::DictionarySP dict_sp =
+      std::make_shared<StructuredData::Dictionary>();
+
+  auto flatten_asi_dict = [&dict_sp](ConstString key,
+                                     StructuredData::Object *val) -> bool {
+    if (!val)
+      return false;
+
+    StructuredData::Array *arr = val->GetAsArray();
+    if (!arr || !arr->GetSize())
+      return false;
+
+    dict_sp->AddItem(key.AsCString(), arr->GetItemAtIndex(0));
+    return true;
+  };
+
+  asi->ForEach(flatten_asi_dict);
+
+  return dict_sp;
+}
+
 void PlatformDarwin::AddClangModuleCompilationOptionsForSDKType(
     Target *target, std::vector<std::string> &options, XcodeSDK::Type sdk_type) {
   const std::vector<std::string> apple_arguments = {

diff  --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
index 334410e91b4a2..36b52f4ca9eb3 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -154,6 +154,10 @@ class PlatformDarwin : public PlatformPOSIX {
   ///     \b nullptr if process has no crash information annotations.
   StructuredData::ArraySP ExtractCrashInfoAnnotations(Process &process);
 
+  /// Extract the `Application Specific Information` messages from a crash
+  /// report.
+  StructuredData::DictionarySP ExtractAppSpecificInfo(Process &process);
+
   void ReadLibdispatchOffsetsAddress(Process *process);
 
   void ReadLibdispatchOffsets(Process *process);

diff  --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
index 174c00e985595..e31d8bb769f85 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp
@@ -485,6 +485,19 @@ ScriptedProcess::GetLoadedDynamicLibrariesInfos() {
   return loaded_images_sp;
 }
 
+lldb_private::StructuredData::DictionarySP ScriptedProcess::GetMetadata() {
+  CheckInterpreterAndScriptObject();
+
+  StructuredData::DictionarySP metadata_sp = GetInterface().GetMetadata();
+
+  Status error;
+  if (!metadata_sp || !metadata_sp->GetSize())
+    return ScriptedInterface::ErrorWithMessage<StructuredData::DictionarySP>(
+        LLVM_PRETTY_FUNCTION, "No metadata.", error);
+
+  return metadata_sp;
+}
+
 ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
   return m_interpreter->GetScriptedProcessInterface();
 }

diff  --git a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
index 465ef7b64ecd7..e8f8dd4a965d5 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -59,8 +59,6 @@ class ScriptedProcess : public Process {
 
   llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }
 
-  SystemRuntime *GetSystemRuntime() override { return nullptr; }
-
   Status DoLoadCore() override;
 
   Status DoLaunch(Module *exe_module, ProcessLaunchInfo &launch_info) override;
@@ -88,6 +86,8 @@ class ScriptedProcess : public Process {
   lldb_private::StructuredData::ObjectSP
   GetLoadedDynamicLibrariesInfos() override;
 
+  lldb_private::StructuredData::DictionarySP GetMetadata() override;
+
 protected:
   ScriptedProcess(lldb::TargetSP target_sp, lldb::ListenerSP listener_sp,
                   const ScriptedProcess::ScriptedProcessInfo &launch_info,

diff  --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
index b19331b5b1082..f13cdd3a4c33c 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
+++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.cpp
@@ -343,3 +343,16 @@ std::shared_ptr<DynamicRegisterInfo> ScriptedThread::GetDynamicRegisterInfo() {
 
   return m_register_info_sp;
 }
+
+StructuredData::ObjectSP ScriptedThread::FetchThreadExtendedInfo() {
+  CheckInterpreterAndScriptObject();
+
+  Status error;
+  StructuredData::ArraySP extended_info_sp = GetInterface()->GetExtendedInfo();
+
+  if (!extended_info_sp || !extended_info_sp->GetSize())
+    return ScriptedInterface::ErrorWithMessage<StructuredData::ObjectSP>(
+        LLVM_PRETTY_FUNCTION, "No extended information found", error);
+
+  return extended_info_sp;
+}

diff  --git a/lldb/source/Plugins/Process/scripted/ScriptedThread.h b/lldb/source/Plugins/Process/scripted/ScriptedThread.h
index 959f498edf240..cd224d60ceef8 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedThread.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.h
@@ -58,6 +58,8 @@ class ScriptedThread : public lldb_private::Thread {
 
   void ClearStackFrames() override;
 
+  StructuredData::ObjectSP FetchThreadExtendedInfo() override;
+
 private:
   void CheckInterpreterAndScriptObject() const;
   lldb::ScriptedThreadInterfaceSP GetInterface() const;

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
index 576bf69c9258e..ffce8c468cab8 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
@@ -177,4 +177,15 @@ ScriptedProcessPythonInterface::CreateScriptedThreadInterface() {
   return std::make_shared<ScriptedThreadPythonInterface>(m_interpreter);
 }
 
+StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() {
+  Status error;
+  StructuredData::DictionarySP dict =
+      Dispatch<StructuredData::DictionarySP>("get_process_metadata", error);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error))
+    return {};
+
+  return dict;
+}
+
 #endif

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
index 7f458b1dd9bdb..622d225853040 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -57,6 +57,8 @@ class ScriptedProcessPythonInterface : public ScriptedProcessInterface,
 
   llvm::Optional<std::string> GetScriptedThreadPluginName() override;
 
+  StructuredData::DictionarySP GetMetadata() override;
+
 private:
   lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override;
 };

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
index 3ff592fb83cd7..d52a9c2d81f97 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp
@@ -144,4 +144,15 @@ ScriptedThreadPythonInterface::GetRegisterContext() {
   return obj->GetAsString()->GetValue().str();
 }
 
+StructuredData::ArraySP ScriptedThreadPythonInterface::GetExtendedInfo() {
+  Status error;
+  StructuredData::ArraySP arr =
+      Dispatch<StructuredData::ArraySP>("get_extended_info", error);
+
+  if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, arr, error))
+    return {};
+
+  return arr;
+}
+
 #endif

diff  --git a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
index 59bb182ae3f3d..63ce1c1ab288f 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
@@ -42,6 +42,8 @@ class ScriptedThreadPythonInterface : public ScriptedThreadInterface,
   StructuredData::DictionarySP GetRegisterInfo() override;
 
   llvm::Optional<std::string> GetRegisterContext() override;
+
+  StructuredData::ArraySP GetExtendedInfo() override;
 };
 } // namespace lldb_private
 

diff  --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 7a56264f87c9b..d4d164a77d732 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -502,6 +502,46 @@ ThreadSP SystemRuntimeMacOSX::GetExtendedBacktraceThread(ThreadSP real_thread,
         m_page_to_free_size = ret.item_buffer_size;
       }
     }
+  } else if (type == "Application Specific Backtrace") {
+    StructuredData::ObjectSP thread_extended_sp =
+        real_thread->GetExtendedInfo();
+
+    if (!thread_extended_sp)
+      return {};
+
+    StructuredData::Array *thread_extended_info =
+        thread_extended_sp->GetAsArray();
+
+    if (!thread_extended_info || !thread_extended_info->GetSize())
+      return {};
+
+    std::vector<addr_t> app_specific_backtrace_pcs;
+
+    auto extract_frame_pc =
+        [&app_specific_backtrace_pcs](StructuredData::Object *obj) -> bool {
+      if (!obj)
+        return false;
+
+      StructuredData::Dictionary *dict = obj->GetAsDictionary();
+      if (!dict)
+        return false;
+
+      lldb::addr_t pc = LLDB_INVALID_ADDRESS;
+      if (!dict->GetValueForKeyAsInteger("pc", pc))
+        return false;
+
+      app_specific_backtrace_pcs.push_back(pc);
+
+      return pc != LLDB_INVALID_ADDRESS;
+    };
+
+    if (!thread_extended_info->ForEach(extract_frame_pc))
+      return {};
+
+    originating_thread_sp =
+        std::make_shared<HistoryThread>(*m_process, real_thread->GetIndexID(),
+                                        app_specific_backtrace_pcs, true);
+    originating_thread_sp->SetQueueName(type.AsCString());
   }
   return originating_thread_sp;
 }
@@ -674,6 +714,7 @@ const std::vector<ConstString> &
 SystemRuntimeMacOSX::GetExtendedBacktraceTypes() {
   if (m_types.size() == 0) {
     m_types.push_back(ConstString("libdispatch"));
+    m_types.push_back(ConstString("Application Specific Backtrace"));
     // We could have pthread as another type in the future if we have a way of
     // gathering that information & it's useful to distinguish between them.
   }

diff  --git a/lldb/test/API/functionalities/process_crash_info/TestProcessCrashInfo.py b/lldb/test/API/functionalities/process_crash_info/TestProcessCrashInfo.py
index 659539c28a795..c0d380aca2849 100644
--- a/lldb/test/API/functionalities/process_crash_info/TestProcessCrashInfo.py
+++ b/lldb/test/API/functionalities/process_crash_info/TestProcessCrashInfo.py
@@ -38,7 +38,7 @@ def test_cli(self):
 
         self.expect('process status --verbose',
                     patterns=["Extended Crash Information",
-                              "crash-info annotations",
+                              "Crash-Info Annotations",
                               "pointer being freed was not allocated"])
 
 

diff  --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.ips b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.ips
new file mode 100644
index 0000000000000..8d151a3be0370
--- /dev/null
+++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.ips
@@ -0,0 +1,131 @@
+{"app_name":"asi","timestamp":"2022-10-07 11:31:53.00 -0700","app_version":"","slice_uuid":"2cee52c2-2d9c-3e64-bdd0-c43ccd1b37ec","build_version":"","platform":1,"share_with_app_devs":0,"is_first_party":1,"bug_type":"309","os_version":"macOS 13.0","roots_installed":0,"incident_id":"E62DF457-8BBC-4E92-AECA-11D1B55246E3","name":"asi"}
+{
+  "uptime" : 90000,
+  "procRole" : "Unspecified",
+  "version" : 2,
+  "userID" : 501,
+  "deployVersion" : 210,
+  "modelCode" : "Mac13,1",
+  "coalitionID" : 495,
+  "osVersion" : {
+    "train" : "macOS 13.0",
+    "build" : "",
+    "releaseType" : ""
+  },
+  "captureTime" : "2022-10-07 11:31:52.6211 -0700",
+  "incident" : "E62DF457-8BBC-4E92-AECA-11D1B55246E3",
+  "pid" : 96535,
+  "translated" : false,
+  "cpuType" : "ARM-64",
+  "roots_installed" : 0,
+  "bug_type" : "309",
+  "procLaunch" : "2022-10-07 11:31:52.4969 -0700",
+  "procStartAbsTime" : 2167631132529,
+  "procExitAbsTime" : 2167634104978,
+  "procName" : "asi",
+  "procPath" : "\/Users\/USER\/*\/asi",
+  "parentProc" : "zsh",
+  "parentPid" : 96199,
+  "coalitionName" : "com.apple.Terminal",
+  "crashReporterKey" : "533C17C1-DBB1-4134-1FDE-68346F18AAA2",
+  "responsiblePid" : 615,
+  "responsibleProc" : "Terminal",
+  "wakeTime" : 1351,
+  "sleepWakeUUID" : "AD23E0A0-A4A5-4B6B-925F-2FC3665C17BF",
+  "sip" : "enabled",
+  "exception" : {"codes":"0x0000000000000000, 0x0000000000000000","rawCodes":[0,0],"type":"EXC_CRASH","signal":"SIGABRT"},
+  "asi" : {"CoreFoundation":["*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 10 beyond bounds [0 .. 3]'"],"libsystem_c.dylib":["abort() called"],"libc++abi.dylib":["terminating with uncaught exception of type NSException"]},
+  "asiBacktraces" : ["0   CoreFoundation                      0x00000001a0a58418 __exceptionPreprocess + 176\n1   libobjc.A.dylib                     0x00000001a05a2ea8 objc_exception_throw + 60\n2   CoreFoundation                      0x00000001a0b3dcc4 -[__NSCFString characterAtIndex:].cold.1 + 0\n3   CoreFoundation                      0x00000001a0b46af4 -[__NSArrayI getObjects:range:].cold.1 + 0\n4   CoreFoundation                      0x00000001a09a12a4 __CFPropertyListIsArrayPlistAux + 0\n5   asi                                 0x00000001047e3ed0 main + 128\n6   dyld                                0x00000001a05d3e50 start + 2544"],
+  "extMods" : {"caller":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"system":{"thread_create":0,"thread_set_state":4,"task_for_pid":4},"targeted":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"warnings":0},
+  "lastExceptionBacktrace" : [{"imageOffset":1033228,"symbol":"__exceptionPreprocess","symbolLocation":164,"imageIndex":5},{"imageOffset":110248,"symbol":"objc_exception_throw","symbolLocation":60,"imageIndex":4},{"imageOffset":1973444,"symbol":"-[__NSCFString characterAtIndex:].cold.1","symbolLocation":0,"imageIndex":5},{"imageOffset":2009844,"symbol":"-[__NSArrayI getObjects:range:].cold.1","symbolLocation":0,"imageIndex":5},{"imageOffset":283300,"symbol":"__CFPropertyListIsArrayPlistAux","symbolLocation":0,"imageIndex":5},{"imageOffset":16080,"symbol":"main","symbolLocation":128,"imageIndex":6},{"imageOffset":24144,"symbol":"start","symbolLocation":2544,"imageIndex":7}],
+  "faultingThread" : 0,
+  "threads" : [{"triggered":true,"id":1767667,"threadState":{"x":[{"value":0},{"value":0},{"value":0},{"value":0},{"value":6988476661},{"value":6096540848},{"value":110},{"value":512},{"value":502518818286880576},{"value":502518810403597248},{"value":512},{"value":11},{"value":11},{"value":2095104},{"value":2043},{"value":2195963912},{"value":328},{"value":8604857144},{"value":0},{"value":6},{"value":8522738816,"symbolLocation":0,"symbol":"_main_thread"},{"value":259},{"value":8522739040,"symbolLocation":224,"symbol":"_main_thread"},{"value":105553117118464},{"value":8528036928,"symbolLocation":0,"symbol":"gProcessInfo"},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":6988750060},"cpsr":{"value":1073745920},"fp":{"value":6096540704},"sp":{"value":6096540672},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":6988526116,"matchesCrashFrame":1},"far":{"value":5452680264}},"queue":"com.apple.main-thread","frames":[{"imageOffset":37412,"symbol":"__pthread_kill","symbolLocation":8,"imageIndex":0},{"imageOffset":27884,"symbol":"pthread_kill","symbolLocation":288,"imageIndex":1},{"imageOffset":496328,"symbol":"abort","symbolLocation":180,"imageIndex":2},{"imageOffset":72472,"symbol":"abort_message","symbolLocation":132,"imageIndex":3},{"imageOffset":6668,"symbol":"demangling_terminate_handler()","symbolLocation":336,"imageIndex":3},{"imageOffset":145252,"symbol":"_objc_terminate()","symbolLocation":144,"imageIndex":4},{"imageOffset":69300,"symbol":"std::__terminate(void (*)())","symbolLocation":20,"imageIndex":3},{"imageOffset":80940,"symbol":"__cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*)","symbolLocation":36,"imageIndex":3},{"imageOffset":80856,"symbol":"__cxa_throw","symbolLocation":140,"imageIndex":3},{"imageOffset":110600,"symbol":"objc_exception_throw","symbolLocation":412,"imageIndex":4},{"imageOffset":1973444,"symbol":"_CFThrowFormattedException","symbolLocation":108,"imageIndex":5},{"imageOffset":2009844,"symbol":"__boundsFail","symbolLocation":92,"imageIndex":5},{"imageOffset":283300,"symbol":"-[__NSArrayI objectAtIndex:]","symbolLocation":60,"imageIndex":5},{"imageOffset":16080,"symbol":"main","symbolLocation":128,"imageIndex":6},{"imageOffset":24144,"symbol":"start","symbolLocation":2544,"imageIndex":7}]}],
+  "usedImages" : [
+  {
+    "source" : "P",
+    "arch" : "arm64e",
+    "base" : 6988488704,
+    "size" : 233468,
+    "uuid" : "15147572-bf8d-359e-a6bb-97f4489e7f78",
+    "path" : "\/usr\/lib\/system\/libsystem_kernel.dylib",
+    "name" : "libsystem_kernel.dylib"
+  },
+  {
+    "source" : "P",
+    "arch" : "arm64e",
+    "base" : 6988722176,
+    "size" : 53244,
+    "uuid" : "19a65066-147a-37e1-be56-bd78821ef285",
+    "path" : "\/usr\/lib\/system\/libsystem_pthread.dylib",
+    "name" : "libsystem_pthread.dylib"
+  },
+  {
+    "source" : "P",
+    "arch" : "arm64e",
+    "base" : 6987440128,
+    "size" : 528372,
+    "uuid" : "cd2fafb3-239f-3929-9b9d-ed1768c25159",
+    "path" : "\/usr\/lib\/system\/libsystem_c.dylib",
+    "name" : "libsystem_c.dylib"
+  },
+  {
+    "source" : "P",
+    "arch" : "arm64e",
+    "base" : 6988390400,
+    "size" : 98300,
+    "uuid" : "88025d90-bb66-34a8-8628-91ec5b3fb900",
+    "path" : "\/usr\/lib\/libc++abi.dylib",
+    "name" : "libc++abi.dylib"
+  },
+  {
+    "source" : "P",
+    "arch" : "arm64e",
+    "base" : 6985121792,
+    "size" : 286112,
+    "uuid" : "9a019b6d-aeb6-3a3e-9c74-717c18dd5d43",
+    "path" : "\/usr\/lib\/libobjc.A.dylib",
+    "name" : "libobjc.A.dylib"
+  },
+  {
+    "source" : "P",
+    "arch" : "arm64e",
+    "base" : 6989135872,
+    "CFBundleShortVersionString" : "6.9",
+    "CFBundleIdentifier" : "com.apple.CoreFoundation",
+    "size" : 5079040,
+    "uuid" : "0cb1d6ec-b4ee-33d5-9828-29db31cad6fc",
+    "path" : "\/System\/Library\/Frameworks\/CoreFoundation.framework\/Versions\/A\/CoreFoundation",
+    "name" : "CoreFoundation",
+    "CFBundleVersion" : "1953.1"
+  },
+  {
+    "source" : "P",
+    "arch" : "arm64",
+    "base" : 4370333696,
+    "size" : 16384,
+    "uuid" : "2cee52c2-2d9c-3e64-bdd0-c43ccd1b37ec",
+    "path" : "\/Users\/USER\/*\/asi",
+    "name" : "asi"
+  },
+  {
+    "source" : "P",
+    "arch" : "arm64e",
+    "base" : 6985408512,
+    "size" : 566452,
+    "uuid" : "0d973234-ed2d-3a07-889a-46b424e29ae0",
+    "path" : "\/usr\/lib\/dyld",
+    "name" : "dyld"
+  }
+],
+  "sharedCache" : {
+  "base" : 6984761344,
+  "size" : 3405660160,
+  "uuid" : "5fe7ffdc-ba32-33ba-8827-d3d9094c6bc3"
+},
+  "vmSummary" : "ReadOnly portion of Libraries: Total=861.7M resident=0K(0%) swapped_out_or_unallocated=861.7M(100%)\nWritable regions: Total=666.4M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=666.4M(100%)\n\n                                VIRTUAL   REGION \nREGION TYPE                        SIZE    COUNT (non-coalesced) \n===========                     =======  ======= \nActivity Tracing                   256K        1 \nKernel Alloc Once                   32K        1 \nMALLOC                           154.2M       14 \nMALLOC guard page                   96K        5 \nMALLOC_MEDIUM (reserved)         120.0M        1         reserved VM address space (unallocated)\nMALLOC_NANO (reserved)           384.0M        1         reserved VM address space (unallocated)\nSTACK GUARD                       56.0M        1 \nStack                             8176K        1 \n__AUTH                             307K       58 \n__AUTH_CONST                      3560K      142 \n__DATA                            1494K      136 \n__DATA_CONST                      3988K      144 \n__DATA_DIRTY                       361K       58 \n__LINKEDIT                       763.4M        2 \n__OBJC_CONST                       289K       36 \n__OBJC_RO                         65.1M        1 \n__OBJC_RW                         1983K        1 \n__TEXT                            98.3M      151 \ndyld private memory                256K        1 \nshared memory                       80K        4 \n===========                     =======  ======= \nTOTAL                              1.6G      759 \nTOTAL, minus reserved VM space     1.1G      759 \n",
+  "legacyInfo" : {
+  "threadTriggered" : {
+    "queue" : "com.apple.main-thread"
+  }
+}
+}

diff  --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.yaml b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.yaml
new file mode 100644
index 0000000000000..31042daadd8a9
--- /dev/null
+++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.yaml
@@ -0,0 +1,392 @@
+--- !mach-o
+FileHeader:
+  magic:           0xFEEDFACF
+  cputype:         0x100000C
+  cpusubtype:      0x0
+  filetype:        0x2
+  ncmds:           21
+  sizeofcmds:      1864
+  flags:           0x200085
+  reserved:        0x0
+LoadCommands:
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __PAGEZERO
+    vmaddr:          0
+    vmsize:          4294967296
+    fileoff:         0
+    filesize:        0
+    maxprot:         0
+    initprot:        0
+    nsects:          0
+    flags:           0
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         552
+    segname:         __TEXT
+    vmaddr:          4294967296
+    vmsize:          16384
+    fileoff:         0
+    filesize:        16384
+    maxprot:         5
+    initprot:        5
+    nsects:          6
+    flags:           0
+    Sections:
+      - sectname:        __text
+        segname:         __TEXT
+        addr:            0x100003E50
+        size:            172
+        offset:          0x3E50
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         FF8301D1FD7B05A9FD43019108008052A8431EB8BFC31FB8A0831FB8A1031FF829000094E11340F9E01700F9280000B0000940F9E8030091090000B029010191090100F9090000B029810191090500F9090000B029010291090900F91F0D00F9020000B0428000911A000094E11340F9A0831EF8A0835EF8420180D21D000094E8030091000100F9000000B00080029107000094E01740F908000094A0435EB8FD7B45A9FF830191C0035FD6
+      - sectname:        __stubs
+        segname:         __TEXT
+        addr:            0x100003EFC
+        size:            36
+        offset:          0x3EFC
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000408
+        reserved1:       0x0
+        reserved2:       0xC
+        reserved3:       0x0
+        content:         100000B0100240F900021FD6100000B0100640F900021FD6100000B0100A40F900021FD6
+      - sectname:        __objc_stubs
+        segname:         __TEXT
+        addr:            0x100003F20
+        size:            64
+        offset:          0x3F20
+        align:           5
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x80000400
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         210000B0210040F9100000B0100E40F900021FD6200020D4200020D4200020D4210000B0210440F9100000B0100E40F900021FD6200020D4200020D4200020D4
+      - sectname:        __cstring
+        segname:         __TEXT
+        addr:            0x100003F60
+        size:            26
+        offset:          0x3F60
+        align:           0
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x2
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         4A696D004A61736F6E004A6F6E61730049736D61696C00254000
+      - sectname:        __objc_methname
+        segname:         __TEXT
+        addr:            0x100003F7A
+        size:            34
+        offset:          0x3F7A
+        align:           1
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x2
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         6F626A6563744174496E6465783A00006172726179576974684F626A656374733A00
+      - sectname:        __unwind_info
+        segname:         __TEXT
+        addr:            0x100003F9C
+        size:            72
+        offset:          0x3F9C
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         010000001C000000000000001C000000000000001C00000002000000503E00003400000034000000FD3E00000000000034000000030000000C000100100001000000000000000004
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         312
+    segname:         __DATA_CONST
+    vmaddr:          4294983680
+    vmsize:          16384
+    fileoff:         16384
+    filesize:        16384
+    maxprot:         3
+    initprot:        3
+    nsects:          3
+    flags:           16
+    Sections:
+      - sectname:        __got
+        segname:         __DATA_CONST
+        addr:            0x100004000
+        size:            32
+        offset:          0x4000
+        align:           3
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x6
+        reserved1:       0x3
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '0000000000001080010000000000108002000000000010800300000000001080'
+      - sectname:        __cfstring
+        segname:         __DATA_CONST
+        addr:            0x100004020
+        size:            160
+        offset:          0x4020
+        align:           3
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         0400000000002080C807000000000000603F00000000200003000000000000000400000000002080C807000000000000643F00000000200005000000000000000400000000002080C8070000000000006A3F00000000200005000000000000000400000000002080C807000000000000703F00000000200006000000000000000400000000002080C807000000000000773F0000000000000200000000000000
+      - sectname:        __objc_imageinfo
+        segname:         __DATA_CONST
+        addr:            0x1000040C0
+        size:            8
+        offset:          0x40C0
+        align:           2
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x0
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '0000000040000000'
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         232
+    segname:         __DATA
+    vmaddr:          4295000064
+    vmsize:          16384
+    fileoff:         32768
+    filesize:        16384
+    maxprot:         3
+    initprot:        3
+    nsects:          2
+    flags:           0
+    Sections:
+      - sectname:        __objc_selrefs
+        segname:         __DATA
+        addr:            0x100008000
+        size:            16
+        offset:          0x8000
+        align:           3
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x10000005
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         8A3F0000000010007A3F000000001000
+      - sectname:        __objc_classrefs
+        segname:         __DATA
+        addr:            0x100008010
+        size:            8
+        offset:          0x8010
+        align:           3
+        reloff:          0x0
+        nreloc:          0
+        flags:           0x10000000
+        reserved1:       0x0
+        reserved2:       0x0
+        reserved3:       0x0
+        content:         '0500000000000080'
+  - cmd:             LC_SEGMENT_64
+    cmdsize:         72
+    segname:         __LINKEDIT
+    vmaddr:          4295016448
+    vmsize:          16384
+    fileoff:         49152
+    filesize:        1264
+    maxprot:         1
+    initprot:        1
+    nsects:          0
+    flags:           0
+  - cmd:             LC_DYLD_CHAINED_FIXUPS
+    cmdsize:         16
+    dataoff:         49152
+    datasize:        264
+  - cmd:             LC_DYLD_EXPORTS_TRIE
+    cmdsize:         16
+    dataoff:         49416
+    datasize:        48
+  - cmd:             LC_SYMTAB
+    cmdsize:         24
+    symoff:          49472
+    nsyms:           10
+    stroff:          49664
+    strsize:         224
+  - cmd:             LC_DYSYMTAB
+    cmdsize:         80
+    ilocalsym:       0
+    nlocalsym:       2
+    iextdefsym:      2
+    nextdefsym:      2
+    iundefsym:       4
+    nundefsym:       6
+    tocoff:          0
+    ntoc:            0
+    modtaboff:       0
+    nmodtab:         0
+    extrefsymoff:    0
+    nextrefsyms:     0
+    indirectsymoff:  49632
+    nindirectsyms:   7
+    extreloff:       0
+    nextrel:         0
+    locreloff:       0
+    nlocrel:         0
+  - cmd:             LC_LOAD_DYLINKER
+    cmdsize:         32
+    name:            12
+    Content:         '/usr/lib/dyld'
+    ZeroPadBytes:    7
+  - cmd:             LC_UUID
+    cmdsize:         24
+    uuid:            2CEE52C2-2D9C-3E64-BDD0-C43CCD1B37EC
+  - cmd:             LC_BUILD_VERSION
+    cmdsize:         32
+    platform:        1
+    minos:           851968
+    sdk:             851968
+    ntools:          1
+    Tools:
+      - tool:            3
+        version:         55836672
+  - cmd:             LC_SOURCE_VERSION
+    cmdsize:         16
+    version:         0
+  - cmd:             LC_MAIN
+    cmdsize:         24
+    entryoff:        15952
+    stacksize:       0
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         96
+    dylib:
+      name:            24
+      timestamp:       2
+      current_version: 127992064
+      compatibility_version: 19660800
+    Content:         '/System/Library/Frameworks/Foundation.framework/Versions/C/Foundation'
+    ZeroPadBytes:    3
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         56
+    dylib:
+      name:            24
+      timestamp:       2
+      current_version: 86441984
+      compatibility_version: 65536
+    Content:         '/usr/lib/libSystem.B.dylib'
+    ZeroPadBytes:    6
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         104
+    dylib:
+      name:            24
+      timestamp:       2
+      current_version: 127992064
+      compatibility_version: 9830400
+    Content:         '/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation'
+    ZeroPadBytes:    3
+  - cmd:             LC_LOAD_DYLIB
+    cmdsize:         56
+    dylib:
+      name:            24
+      timestamp:       2
+      current_version: 14942208
+      compatibility_version: 65536
+    Content:         '/usr/lib/libobjc.A.dylib'
+    ZeroPadBytes:    8
+  - cmd:             LC_FUNCTION_STARTS
+    cmdsize:         16
+    dataoff:         49464
+    datasize:        8
+  - cmd:             LC_DATA_IN_CODE
+    cmdsize:         16
+    dataoff:         49472
+    datasize:        0
+  - cmd:             LC_CODE_SIGNATURE
+    cmdsize:         16
+    dataoff:         49888
+    datasize:        528
+LinkEditData:
+  NameList:
+    - n_strx:          156
+      n_type:          0x1E
+      n_sect:          3
+      n_desc:          0
+      n_value:         4294983456
+    - n_strx:          188
+      n_type:          0x1E
+      n_sect:          3
+      n_desc:          0
+      n_value:         4294983488
+    - n_strx:          2
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          16
+      n_value:         4294967296
+    - n_strx:          22
+      n_type:          0xF
+      n_sect:          1
+      n_desc:          0
+      n_value:         4294983248
+    - n_strx:          28
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          256
+      n_value:         0
+    - n_strx:          35
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          768
+      n_value:         0
+    - n_strx:          57
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          768
+      n_value:         0
+    - n_strx:          91
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          1024
+      n_value:         0
+    - n_strx:          116
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          1024
+      n_value:         0
+    - n_strx:          142
+      n_type:          0x1
+      n_sect:          0
+      n_desc:          1024
+      n_value:         0
+  StringTable:
+    - ' '
+    - __mh_execute_header
+    - _main
+    - _NSLog
+    - '_OBJC_CLASS_$_NSArray'
+    - ___CFConstantStringClassReference
+    - _objc_autoreleasePoolPop
+    - _objc_autoreleasePoolPush
+    - _objc_msgSend
+    - '_objc_msgSend$arrayWithObjects:'
+    - '_objc_msgSend$objectAtIndex:'
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+    - ''
+  IndirectSymbols: [ 0x4, 0x7, 0x8, 0x4, 0x7, 0x8, 0x9 ]
+  FunctionStarts:  [ 0x3E50 ]
+...

diff  --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/main.m b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/main.m
new file mode 100644
index 0000000000000..e6745a81333d7
--- /dev/null
+++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/main.m
@@ -0,0 +1,13 @@
+#include <Foundation/Foundation.h>
+
+int main(int argc, char *argv[]) {
+  @autoreleasepool {
+
+    NSArray *crew = [NSArray arrayWithObjects:@"Jim", @"Jason", @"Jonas", @"Ismail", nil];
+
+    // This will throw an exception.
+    NSLog(@"%@", [crew objectAtIndex:10]);
+  }
+
+  return 0;
+}

diff  --git a/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test
new file mode 100644
index 0000000000000..266b1b4ee404d
--- /dev/null
+++ b/lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test
@@ -0,0 +1,52 @@
+# REQUIRES: python, native && target-aarch64 && system-darwin
+
+# RUN: mkdir -p %t.dir
+# RUN: yaml2obj %S/Inputs/application_specific_info/asi.yaml > %t.dir/asi
+# RUN: %lldb -o 'command script import lldb.macosx.crashlog' \
+# RUN: -o 'crashlog -a -i -t %t.dir/asi %S/Inputs/application_specific_info/asi.ips' \
+# RUN: -o "thread list" -o "bt all" 2>&1 | FileCheck %s
+
+# CHECK: "crashlog" {{.*}} commands have been installed, use the "--help" options on these commands
+
+# CHECK: (lldb) process status --verbose
+# CHECK-NEXT: Process 96535 stopped
+# CHECK-NEXT: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0)
+# CHECK-NEXT:     frame #0: 0x00000001a08c7224{{.*}}[artificial]
+# CHECK: Extended Crash Information:
+# CHECK:   Application Specific Information:
+# CHECK-NEXT:     CoreFoundation: *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** __boundsFail: index 10 beyond bounds [0 .. 3]'
+# CHECK-NEXT:     libc++abi.dylib: terminating with uncaught exception of type NSException
+# CHECK-NEXT:     libsystem_c.dylib: abort() called
+
+
+# CHECK: (lldb) thread backtrace --extended true
+# CHECK-NEXT: * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0)
+# CHECK-NEXT:   * frame #0: 0x00000001a08c7224{{.*}}[artificial]
+# CHECK-NEXT:     frame #1: 0x00000001a08fdceb{{.*}}[artificial]
+# CHECK-NEXT:     frame #2: 0x00000001a08372c7{{.*}}[artificial]
+# CHECK-NEXT:     frame #3: 0x00000001a08b7b17{{.*}}[artificial]
+# CHECK-NEXT:     frame #4: 0x00000001a08a7a0b{{.*}}[artificial]
+# CHECK-NEXT:     frame #5: 0x00000001a05ab763{{.*}}[artificial]
+# CHECK-NEXT:     frame #6: 0x00000001a08b6eb3{{.*}}[artificial]
+# CHECK-NEXT:     frame #7: 0x00000001a08b9c2b{{.*}}[artificial]
+# CHECK-NEXT:     frame #8: 0x00000001a08b9bd7{{.*}}[artificial]
+# CHECK-NEXT:     frame #9: 0x00000001a05a3007{{.*}}[artificial]
+# CHECK-NEXT:     frame #10: 0x00000001a0b3dcc3{{.*}}[artificial]
+# CHECK-NEXT:     frame #11: 0x00000001a0b46af3{{.*}}[artificial]
+# CHECK-NEXT:     frame #12: 0x00000001a09a12a3{{.*}}[artificial]
+# CHECK-NEXT:     frame #13: 0x00000001047e3ecf asi`main{{.*}}[artificial]
+# CHECK-NEXT:     frame #14: 0x00000001a05d3e4f{{.*}}[artificial]
+
+# CHECK:   thread #4294967295: tid = 0x0001, 0x00000001a0a58418{{.*}}, queue = 'Application Specific Backtrace'
+# CHECK-NEXT:     frame #0: 0x00000001a0a58418{{.*}}
+# CHECK-NEXT:     frame #1: 0x00000001a05a2ea7{{.*}}
+# CHECK-NEXT:     frame #2: 0x00000001a0b3dcc3{{.*}}
+# CHECK-NEXT:     frame #3: 0x00000001a0b46af3{{.*}}
+# CHECK-NEXT:     frame #4: 0x00000001a09a12a3{{.*}}
+# CHECK-NEXT:     frame #5: 0x00000001047e3ecf asi`main{{.*}}
+# CHECK-NEXT:     frame #6: 0x00000001a05d3e4f dyld`start{{.*}}
+
+
+# CHECK: (lldb) thread list
+# CHECK-NEXT: Process 96535 stopped
+# CHECK-NEXT: * thread #1: tid = 0x1af8f3, 0x00000001a08c7224{{.*}}, queue = 'com.apple.main-thread', stop reason = EXC_CRASH (code=0, subcode=0x0)


        


More information about the lldb-commits mailing list