[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