Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/llvm/llvm-project.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lldb
diff options
context:
space:
mode:
authorMed Ismail Bennani <medismail.bennani@gmail.com>2022-11-04 00:27:28 +0300
committerMed Ismail Bennani <medismail.bennani@gmail.com>2022-11-04 00:44:53 +0300
commit78d6e1d1d4b3b5c6bdd779256c915a8ac7148174 (patch)
tree55401583ff5cca21aead3ba0ec2caf3db9d977aa /lldb
parente861d053dd43f2e5a63f150ee2f9d1d643ea29c1 (diff)
[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@gmail.com>
Diffstat (limited to 'lldb')
-rwxr-xr-xlldb/examples/python/crashlog.py35
-rw-r--r--lldb/examples/python/scripted_process/crashlog_scripted_process.py59
-rw-r--r--lldb/examples/python/scripted_process/scripted_process.py22
-rw-r--r--lldb/include/lldb/Interpreter/ScriptedProcessInterface.h4
-rw-r--r--lldb/include/lldb/Target/Process.h7
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp53
-rw-r--r--lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h4
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp13
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedProcess.h4
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedThread.cpp13
-rw-r--r--lldb/source/Plugins/Process/scripted/ScriptedThread.h2
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp11
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h2
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.cpp11
-rw-r--r--lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h2
-rw-r--r--lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp41
-rw-r--r--lldb/test/API/functionalities/process_crash_info/TestProcessCrashInfo.py2
-rw-r--r--lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.ips131
-rw-r--r--lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/asi.yaml392
-rw-r--r--lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/application_specific_info/main.m13
-rw-r--r--lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test52
21 files changed, 847 insertions, 26 deletions
diff --git a/lldb/examples/python/crashlog.py b/lldb/examples/python/crashlog.py
index 8aaf7c165684..47250f3b350f 100755
--- a/lldb/examples/python/crashlog.py
+++ b/lldb/examples/python/crashlog.py
@@ -462,6 +462,12 @@ class JSONCrashLogParser(CrashLogParser):
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 @@ class JSONCrashLogParser(CrashLogParser):
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 load_crashlog_in_scripted_process(debugger, crash_log_file, options, result)
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 e64b9b7822af..55c50917c9d6 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 @@ class CrashLogScriptedProcess(ScriptedProcess):
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 @@ class CrashLogScriptedProcess(ScriptedProcess):
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 @@ class CrashLogScriptedProcess(ScriptedProcess):
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 @@ class CrashLogScriptedProcess(ScriptedProcess):
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 @@ class CrashLogScriptedThread(ScriptedThread):
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 @@ class CrashLogScriptedThread(ScriptedThread):
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 @@ class CrashLogScriptedThread(ScriptedThread):
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 @@ class CrashLogScriptedThread(ScriptedThread):
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 48966f8385cb..43eb97dbd772 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 @@ class ScriptedProcess(metaclass=ABCMeta):
self.args = args
self.threads = {}
self.loaded_images = []
+ self.metadata = {}
@abstractmethod
def get_memory_region_containing_address(self, addr):
@@ -138,7 +140,6 @@ class ScriptedProcess(metaclass=ABCMeta):
"""
return 0
-
def launch(self):
""" Simulate the scripted process launch.
@@ -191,6 +192,15 @@ class ScriptedProcess(metaclass=ABCMeta):
"""
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 @@ class ScriptedThread(metaclass=ABCMeta):
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 @@ class ScriptedThread(metaclass=ABCMeta):
"""
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 905623e575f7..164ec9b9dd60 100644
--- a/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
+++ b/lldb/include/lldb/Interpreter/ScriptedProcessInterface.h
@@ -66,6 +66,8 @@ public:
return llvm::None;
}
+ virtual StructuredData::DictionarySP GetMetadata() { return nullptr; }
+
protected:
friend class ScriptedThread;
virtual lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() {
@@ -99,6 +101,8 @@ public:
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 6975eb8029de..b9995c2a4432 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 21b733a62bbb..9d89148616be 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 334410e91b4a..36b52f4ca9eb 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h
@@ -154,6 +154,10 @@ protected:
/// \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 174c00e98559..e31d8bb769f8 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 465ef7b64ecd..e8f8dd4a965d 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedProcess.h
@@ -59,8 +59,6 @@ public:
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 @@ public:
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 b19331b5b108..f13cdd3a4c33 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 959f498edf24..cd224d60ceef 100644
--- a/lldb/source/Plugins/Process/scripted/ScriptedThread.h
+++ b/lldb/source/Plugins/Process/scripted/ScriptedThread.h
@@ -58,6 +58,8 @@ public:
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 576bf69c9258..ffce8c468cab 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 7f458b1dd9bd..622d22585304 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
@@ -57,6 +57,8 @@ public:
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 3ff592fb83cd..d52a9c2d81f9 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 59bb182ae3f3..63ce1c1ab288 100644
--- a/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
+++ b/lldb/source/Plugins/ScriptInterpreter/Python/ScriptedThreadPythonInterface.h
@@ -42,6 +42,8 @@ public:
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 7a56264f87c9..d4d164a77d73 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 659539c28a79..c0d380aca284 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 @@ class PlatformProcessCrashInfoTestCase(TestBase):
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 000000000000..8d151a3be037
--- /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 000000000000..31042daadd8a
--- /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 000000000000..e6745a81333d
--- /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 000000000000..266b1b4ee404
--- /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)