mib updated this revision to Diff 465232.
mib marked 2 inline comments as done.
mib retitled this revision from "[lldb/crashlog] Add support for Application 
Specific Backtraces" to "[lldb/crashlog] Add support for Application Specific 
Backtraces & Information".
mib edited the summary of this revision.
mib added a reviewer: jingham.
mib added a comment.

- Add test (wip)
- Add Application Specific Information to process extended crash info
- Add {,Scripted}Process::GetMetadata method


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126260/new/

https://reviews.llvm.org/D126260

Files:
  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/ScriptInterpreter/Python/ScriptedProcessPythonInterface.cpp
  lldb/source/Plugins/ScriptInterpreter/Python/ScriptedProcessPythonInterface.h
  lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/asi.ips
  lldb/test/Shell/ScriptInterpreter/Python/Crashlog/Inputs/main.m
  
lldb/test/Shell/ScriptInterpreter/Python/Crashlog/app_specific_backtrace_crashlog.test

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
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 <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;
+}
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/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<std::string> 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<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
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<StructuredData::DictionarySP>(
+        LLVM_PRETTY_FUNCTION, "No metadata.", error);
+
+  return metadata_sp;
+}
+
 ScriptedProcessInterface &ScriptedProcess::GetInterface() const {
   return m_interpreter->GetScriptedProcessInterface();
 }
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<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 @@
   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<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 = {
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/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/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/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/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():
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to