Index: lldb/examples/python/crashlog.py =================================================================== --- lldb/examples/python/crashlog.py +++ lldb/examples/python/crashlog.py @@ -462,6 +462,10 @@ 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']) self.parse_errors(self.data) thread = self.crashlog.threads[self.crashlog.crashed_thread_idx] reason = self.parse_crash_reason(self.data['exception']) @@ -573,6 +577,31 @@ self.crashlog.threads.append(thread) idx += 1 + def parse_app_specific_backtraces(self, json_app_specific_bts): + 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 + + for idx, backtrace in enumerate(json_app_specific_bts): + thread = self.crashlog.Thread(idx, True) + thread.queue = "Application Specific Backtrace" + if parse_asi_backtrace(self, 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(): Index: lldb/examples/python/scripted_process/crashlog_scripted_process.py =================================================================== --- lldb/examples/python/scripted_process/crashlog_scripted_process.py +++ lldb/examples/python/scripted_process/crashlog_scripted_process.py @@ -18,6 +18,7 @@ self.crashed_thread_idx = crash_log.crashed_thread_idx self.loaded_images = [] self.exception = crash_log.exception + self.metadata['asi'] = crash_log.asi def load_images(self, images): #TODO: Add to self.loaded_images and load images in lldb @@ -103,6 +104,9 @@ 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: @@ -145,6 +149,8 @@ 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) self.queue = self.backing_thread.queue self.has_crashed = (self.scripted_process.crashed_thread_idx == self.idx) self.create_stackframes() Index: lldb/examples/python/scripted_process/scripted_process.py =================================================================== --- lldb/examples/python/scripted_process/scripted_process.py +++ lldb/examples/python/scripted_process/scripted_process.py @@ -18,6 +18,7 @@ stack_memory_dump = None loaded_images = None threads = None + metadata = None @abstractmethod def __init__(self, target, args): @@ -41,6 +42,7 @@ self.args = args self.threads = {} self.loaded_images = [] + self.metadata = {} @abstractmethod def get_memory_region_containing_address(self, addr): @@ -138,7 +140,6 @@ """ return 0 - def launch(self): """ Simulate the scripted process launch. @@ -191,6 +192,15 @@ """ 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): """ Index: lldb/include/lldb/Interpreter/ScriptedProcessInterface.h =================================================================== --- lldb/include/lldb/Interpreter/ScriptedProcessInterface.h +++ lldb/include/lldb/Interpreter/ScriptedProcessInterface.h @@ -66,6 +66,8 @@ return llvm::None; } + virtual StructuredData::DictionarySP GetMetadata() { return nullptr; } + protected: friend class ScriptedThread; virtual lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() { Index: lldb/include/lldb/Target/Process.h =================================================================== --- lldb/include/lldb/Target/Process.h +++ lldb/include/lldb/Target/Process.h @@ -2423,6 +2423,13 @@ 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; Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.h @@ -154,6 +154,10 @@ /// \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); Index: lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp =================================================================== --- lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp +++ lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp @@ -857,21 +857,20 @@ llvm::Expected 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(); - 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 @@ 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 nullptr; + + StructuredData::Dictionary *asi; + if (!metadata_sp->GetValueForKeyAsDictionary("asi", asi)) + return nullptr; + + StructuredData::DictionarySP dict_sp = + std::make_shared(); + + 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 &options, XcodeSDK::Type sdk_type) { const std::vector apple_arguments = { Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.h =================================================================== --- lldb/source/Plugins/Process/scripted/ScriptedProcess.h +++ lldb/source/Plugins/Process/scripted/ScriptedProcess.h @@ -88,6 +88,8 @@ 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, Index: lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp =================================================================== --- lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp +++ lldb/source/Plugins/Process/scripted/ScriptedProcess.cpp @@ -485,6 +485,20 @@ return loaded_images_sp; } +lldb_private::StructuredData::DictionarySP ScriptedProcess::GetMetadata() { + CheckInterpreterAndScriptObject(); + + Status error; + + StructuredData::DictionarySP metadata_sp = GetInterface().GetMetadata(); + + if (!metadata_sp || !metadata_sp->GetSize()) + return GetInterface().ErrorWithMessage( + LLVM_PRETTY_FUNCTION, "No metadata.", error); + + return metadata_sp; +} + ScriptedProcessInterface &ScriptedProcess::GetInterface() const { return m_interpreter->GetScriptedProcessInterface(); } Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h =================================================================== --- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h +++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h @@ -57,6 +57,8 @@ llvm::Optional GetScriptedThreadPluginName() override; + StructuredData::DictionarySP GetMetadata() override; + private: lldb::ScriptedThreadInterfaceSP CreateScriptedThreadInterface() override; }; Index: lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp =================================================================== --- lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp +++ lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp @@ -177,4 +177,15 @@ return std::make_shared(m_interpreter); } +StructuredData::DictionarySP ScriptedProcessPythonInterface::GetMetadata() { + Status error; + StructuredData::DictionarySP dict = + Dispatch("get_process_metadata", error); + + if (!CheckStructuredDataObject(LLVM_PRETTY_FUNCTION, dict, error)) + return {}; + + return dict; +} + #endif Index: lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/asi.ips =================================================================== --- /dev/null +++ lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/asi.ips @@ -0,0 +1,131 @@ +{"app_name":"main","timestamp":"2022-06-01 10:58:47.00 -0700","app_version":"","slice_uuid":"d6c2f273-1799-32a6-954d-a0e6c8d68ea1","build_version":"","platform":1,"share_with_app_devs":0,"is_first_party":1,"bug_type":"309","os_version":"macOS 11.3","roots_installed":0,"incident_id":"0D36AADE-D172-4520-84A4-761E5D5EA735","name":"main"} +{ + "uptime" : 16000, + "procRole" : "Unspecified", + "version" : 2, + "userID" : 501, + "deployVersion" : 210, + "modelCode" : "MacBookPro18,2", + "coalitionID" : 1173, + "osVersion" : { + "train" : "macOS 11.3", + "build" : "", + "releaseType" : "" + }, + "captureTime" : "2022-06-01 10:58:47.4352 -0700", + "incident" : "0D36AADE-D172-4520-84A4-761E5D5EA735", + "pid" : 11680, + "translated" : false, + "cpuType" : "ARM-64", + "roots_installed" : 0, + "bug_type" : "309", + "procLaunch" : "2022-06-01 10:58:47.4186 -0700", + "procStartAbsTime" : 394114582362, + "procExitAbsTime" : 394114924657, + "procName" : "@NAME@", + "procPath" : "@EXEC@", + "parentProc" : "zsh", + "parentPid" : 10778, + "coalitionName" : "com.apple.Terminal", + "crashReporterKey" : "CDC11418-EDBF-2A49-0D83-8B441A5004B0", + "responsiblePid" : 2692, + "responsibleProc" : "Terminal", + "wakeTime" : 3299, + "sleepWakeUUID" : "1FD4637D-A1C0-426D-840C-C812A39871EF", + "sip" : "disabled", + "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 .. 2]'"],"libsystem_c.dylib":["abort() called"],"libc++abi.dylib":["terminating with uncaught exception of type NSException"]}, + "asiBacktraces" : ["0 CoreFoundation 0x0000000184255b2c __exceptionPreprocess + 176\n1 libobjc.A.dylib 0x0000000183e2d458 objc_exception_throw + 60\n2 CoreFoundation 0x0000000184336ce4 -[__NSCFString characterAtIndex:].cold.1 + 0\n3 CoreFoundation 0x000000018433fa54 -[__NSArrayI getObjects:range:].cold.1 + 0\n4 CoreFoundation 0x000000018419db24 __CFPropertyListIsArrayPlistAux + 0\n5 main 0x0000000104a9fef0 main + 116\n6 dyld 0x0000000210861c10 start + 2368"], + "extMods" : {"caller":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"system":{"thread_create":0,"thread_set_state":108,"task_for_pid":6},"targeted":{"thread_create":0,"thread_set_state":0,"task_for_pid":0},"warnings":0}, + "lastExceptionBacktrace" : [{"imageOffset":1039136,"symbol":"__exceptionPreprocess","symbolLocation":164,"imageIndex":5},{"imageOffset":103512,"symbol":"objc_exception_throw","symbolLocation":60,"imageIndex":4},{"imageOffset":1961188,"symbol":"-[__NSCFString characterAtIndex:].cold.1","symbolLocation":0,"imageIndex":5},{"imageOffset":1997396,"symbol":"-[__NSArrayI getObjects:range:].cold.1","symbolLocation":0,"imageIndex":5},{"imageOffset":285476,"symbol":"__CFPropertyListIsArrayPlistAux","symbolLocation":0,"imageIndex":5},{"imageOffset":16112,"sourceLine":12,"sourceFile":"main.m","symbol":"main","imageIndex":6,"symbolLocation":116},{"imageOffset":23568,"sourceLine":1146,"sourceFile":"dyldMain.cpp","symbol":"start","imageIndex":7,"symbolLocation":2368}], + "faultingThread" : 0, + "threads" : [{"triggered":true,"id":282240,"threadState":{"x":[{"value":0},{"value":0},{"value":0},{"value":0},{"value":6510309621},{"value":6093673392},{"value":110},{"value":512},{"value":198313875947341530},{"value":198313866827717658},{"value":512},{"value":11},{"value":11},{"value":0},{"value":0},{"value":6510309659},{"value":328},{"value":8226535912},{"value":0},{"value":6},{"value":9186810560,"symbolLocation":0,"symbol":"_main_thread"},{"value":259},{"value":9186810784,"symbolLocation":224,"symbol":"_main_thread"},{"value":5269110912},{"value":6093679392},{"value":0},{"value":0},{"value":0},{"value":0}],"flavor":"ARM_THREAD_STATE64","lr":{"value":6510583568},"cpsr":{"value":1073745920},"fp":{"value":6093673248},"sp":{"value":6093673216},"esr":{"value":1442840704,"description":" Address size fault"},"pc":{"value":6510359204,"matchesCrashFrame":1},"far":{"value":5276518984}},"queue":"com.apple.main-thread","frames":[{"imageOffset":37540,"symbol":"__pthread_kill","symbolLocation":8,"imageIndex":0},{"imageOffset":28432,"symbol":"pthread_kill","symbolLocation":288,"imageIndex":1},{"imageOffset":496344,"sourceLine":118,"sourceFile":"abort.c","symbol":"abort","imageIndex":2,"symbolLocation":180},{"imageOffset":72472,"sourceLine":78,"sourceFile":"abort_message.cpp","symbol":"abort_message","imageIndex":3,"symbolLocation":132},{"imageOffset":6668,"sourceLine":71,"sourceFile":"cxa_default_handlers.cpp","symbol":"demangling_terminate_handler()","imageIndex":3,"symbolLocation":336},{"imageOffset":138932,"symbol":"_objc_terminate()","symbolLocation":144,"imageIndex":4},{"imageOffset":69300,"sourceLine":59,"sourceFile":"cxa_handlers.cpp","symbol":"std::__terminate(void (*)())","imageIndex":3,"symbolLocation":20},{"imageOffset":80940,"sourceLine":152,"sourceFile":"cxa_exception.cpp","symbol":"__cxxabiv1::failed_throw(__cxxabiv1::__cxa_exception*)","imageIndex":3,"symbolLocation":36},{"imageOffset":80856,"sourceLine":283,"sourceFile":"cxa_exception.cpp","symbol":"__cxa_throw","imageIndex":3,"symbolLocation":140},{"imageOffset":103864,"symbol":"objc_exception_throw","symbolLocation":412,"imageIndex":4},{"imageOffset":1961188,"symbol":"_CFThrowFormattedException","symbolLocation":108,"imageIndex":5},{"imageOffset":1997396,"symbol":"__boundsFail","symbolLocation":92,"imageIndex":5},{"imageOffset":285476,"symbol":"-[__NSArrayI objectAtIndex:]","symbolLocation":60,"imageIndex":5},{"imageOffset":16112,"sourceLine":12,"sourceFile":"main.m","symbol":"main","imageIndex":6,"symbolLocation":116},{"imageOffset":23568,"sourceLine":1146,"sourceFile":"dyldMain.cpp","symbol":"start","imageIndex":7,"symbolLocation":2368}]}], + "usedImages" : [ + { + "source" : "P", + "arch" : "arm64e", + "base" : 6510321664, + "size" : 233448, + "uuid" : "e113a1b5-ca82-3627-8f50-2eff1f63d2c4", + "path" : "\/usr\/lib\/system\/libsystem_kernel.dylib", + "name" : "libsystem_kernel.dylib" + }, + { + "source" : "P", + "arch" : "arm64e", + "base" : 6510555136, + "size" : 53236, + "uuid" : "de39e254-2433-3a79-80ca-623fe473d3df", + "path" : "\/usr\/lib\/system\/libsystem_pthread.dylib", + "name" : "libsystem_pthread.dylib" + }, + { + "source" : "P", + "arch" : "arm64e", + "base" : 6509273088, + "size" : 528380, + "uuid" : "4448148e-acd1-36ae-8815-3da83dacf996", + "path" : "\/usr\/lib\/system\/libsystem_c.dylib", + "name" : "libsystem_c.dylib" + }, + { + "source" : "P", + "arch" : "arm64e", + "base" : 6510223360, + "size" : 98300, + "uuid" : "9033d2c0-6146-3185-bbff-2a4722d3706b", + "path" : "\/usr\/lib\/libc++abi.dylib", + "name" : "libc++abi.dylib" + }, + { + "source" : "P", + "arch" : "arm64e", + "base" : 6507544576, + "size" : 278160, + "uuid" : "8a8d9f89-cc58-350f-83ab-b4fa92f4c220", + "path" : "\/usr\/lib\/libobjc.A.dylib", + "name" : "libobjc.A.dylib" + }, + { + "source" : "P", + "arch" : "arm64e", + "base" : 6510968832, + "CFBundleShortVersionString" : "6.9", + "CFBundleIdentifier" : "com.apple.CoreFoundation", + "size" : 5058530, + "uuid" : "58049016-375c-357e-94ca-13e5e7e58786", + "path" : "\/System\/Library\/Frameworks\/CoreFoundation.framework\/Versions\/A\/CoreFoundation", + "name" : "CoreFoundation", + "CFBundleVersion" : "1932.101" + }, + { + "source" : "P", + "arch" : "arm64", + "base" : 4373200896, + "size" : 16384, + "uuid" : "@UUID@", + "path" : "@EXEC@", + "name" : "@NAME@" + }, + { + "source" : "P", + "arch" : "arm64e", + "base" : 8867135488, + "size" : 559264, + "uuid" : "d238d2ee-ddec-3f3f-8d6c-c291f4562cea", + "path" : "\/usr\/lib\/dyld", + "name" : "dyld" + } +], + "sharedCache" : { + "base" : 6507184128, + "size" : 3608428544, + "uuid" : "e25018e2-6fd0-3630-84dc-59db100ee143" +}, + "vmSummary" : "ReadOnly portion of Libraries: Total=877.0M resident=0K(0%) swapped_out_or_unallocated=877.0M(100%)\nWritable regions: Total=668.6M written=0K(0%) resident=0K(0%) swapped_out=0K(0%) unallocated=668.6M(100%)\n\n VIRTUAL REGION \nREGION TYPE SIZE COUNT (non-coalesced) \n=========== ======= ======= \nActivity Tracing 256K 1 \nKernel Alloc Once 32K 1 \nMALLOC 156.2M 16 \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 299K 55 \n__AUTH_CONST 3557K 142 \n__DATA 1496K 136 \n__DATA_CONST 3994K 144 \n__DATA_DIRTY 363K 59 \n__LINKEDIT 779.2M 2 \n__OBJC_CONST 286K 36 \n__OBJC_RO 64.1M 1 \n__OBJC_RW 1966K 1 \n__TEXT 97.9M 151 \ndyld private memory 512K 2 \nshared memory 80K 4 \n=========== ======= ======= \nTOTAL 1.6G 760 \nTOTAL, minus reserved VM space 1.1G 760 \n", + "legacyInfo" : { + "threadTriggered" : { + "queue" : "com.apple.main-thread" + } +} +} Index: lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/main.m =================================================================== --- /dev/null +++ lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/main.m @@ -0,0 +1,13 @@ +#include + +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; +} Index: lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test =================================================================== --- /dev/null +++ lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test @@ -0,0 +1,57 @@ +# REQUIRES: python, native && target-aarch64 && system-darwin + +# RUN: %clangxx_host -framework Foundation -g %S/Inputs/main.m -o %t.out + +# RUN: cp %S/Inputs/asi.ips %t.crash +# RUN: %python %S/patch-crashlog.py --binary %t.out --crashlog %t.crash --offsets '{"main":160, "bar":20, "foo":24}' --json +# RUN: %lldb %t.out -o 'command script import lldb.macosx.crashlog' -o 'crashlog -a -i %t.crash' 2>&1 -o "thread list" -o "bt all" | FileCheck %s + +# CHECK: "crashlog" {{.*}} commands have been installed, use the "--help" options on these commands + +# CHECK: (lldb) process status +# CHECK-NEXT: Process 24991 stopped +# CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS +# CHECK-NEXT: frame #0: 0x00000001047f5970 scripted_crashlog_json.test.tmp.out`bar + +# CHECK: (lldb) thread backtrace +# CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS +# CHECK-NEXT: * frame #0: 0x00000001047f5970 scripted_crashlog_json.test.tmp.out`bar +# CHECK-NEXT: frame #1: 0x00000001047f5998 scripted_crashlog_json.test.tmp.out`foo +# CHECK-NEXT: frame #2: 0x00000001047f5b04 scripted_crashlog_json.test.tmp.out`compute_pow +# CHECK-NEXT: frame #3: 0x00000001047f7690 scripted_crashlog_json.test.tmp.out`decltype +# CHECK-NEXT: frame #4: 0x00000001047f7614 scripted_crashlog_json.test.tmp.out`void std::__1::__thread_execute +# CHECK-NEXT: frame #5: 0x00000001047f6d58 scripted_crashlog_json.test.tmp.out`void* std::__1::__thread_proxy +# CHECK-NEXT: frame #6: 0x000000018bf5326c libsystem_pthread.dylib`_pthread_start +# CHECK-NEXT: frame #7: 0x000000018bf4e08c libsystem_pthread.dylib`thread_start + +# CHECK: (lldb) thread list +# CHECK-NEXT: Process 24991 stopped +# CHECK-NEXT: thread #1: tid = 0x4ea840, 0x000000018bf17854 libsystem_kernel.dylib`__ulock_wait{{.*}}, queue = 'com.apple.main-thread' +# CHECK-NEXT: thread #2: tid = 0x4ea850, 0x00000001047f59e8 scripted_crashlog_json.test.tmp.out`call_and_wait +# CHECK-NEXT: * thread #3: tid = 0x4ea851, 0x00000001047f5970 scripted_crashlog_json.test.tmp.out`bar{{.*}}, stop reason = EXC_BAD_ACCESS + + +# CHECK: (lldb) bt all +# CHECK-NEXT: thread #1 +# CHECK-NEXT: frame #0: 0x000000018bf17854 libsystem_kernel.dylib`__ulock_wait +# CHECK-NEXT: frame #1: 0x000000018bf555a0 libsystem_pthread.dylib`_pthread_join +# CHECK-NEXT: frame #2: 0x000000018beae9c0 libc++.1.dylib`std::__1::thread::join +# CHECK-NEXT: frame #3: 0x00000001047f5bb8 scripted_crashlog_json.test.tmp.out`main +# CHECK-NEXT: frame #4: 0x0000000104ae5088 dyld`start +# CHECK-NEXT: thread #2 +# CHECK-NEXT: frame #0: 0x00000001047f59e8 scripted_crashlog_json.test.tmp.out`call_and_wait +# CHECK-NEXT: frame #1: 0x00000001047f59d4 scripted_crashlog_json.test.tmp.out`call_and_wait +# CHECK-NEXT: frame #2: 0x00000001047f7690 scripted_crashlog_json.test.tmp.out`decltype +# CHECK-NEXT: frame #3: 0x00000001047f7614 scripted_crashlog_json.test.tmp.out`void std::__1::__thread_execute +# CHECK-NEXT: frame #4: 0x00000001047f6d58 scripted_crashlog_json.test.tmp.out`void* std::__1::__thread_proxy +# CHECK-NEXT: frame #5: 0x000000018bf5326c libsystem_pthread.dylib`_pthread_start +# CHECK-NEXT: frame #6: 0x000000018bf4e08c libsystem_pthread.dylib`thread_start +# CHECK-NEXT: * thread #3, stop reason = EXC_BAD_ACCESS +# CHECK-NEXT: * frame #0: 0x00000001047f5970 scripted_crashlog_json.test.tmp.out`bar +# CHECK-NEXT: frame #1: 0x00000001047f5998 scripted_crashlog_json.test.tmp.out`foo +# CHECK-NEXT: frame #2: 0x00000001047f5b04 scripted_crashlog_json.test.tmp.out`compute_pow +# CHECK-NEXT: frame #3: 0x00000001047f7690 scripted_crashlog_json.test.tmp.out`decltype +# CHECK-NEXT: frame #4: 0x00000001047f7614 scripted_crashlog_json.test.tmp.out`void std::__1::__thread_execute +# CHECK-NEXT: frame #5: 0x00000001047f6d58 scripted_crashlog_json.test.tmp.out`void* std::__1::__thread_proxy +# CHECK-NEXT: frame #6: 0x000000018bf5326c libsystem_pthread.dylib`_pthread_start +# CHECK-NEXT: frame #7: 0x000000018bf4e08c libsystem_pthread.dylib`thread_start