[Lldb-commits] [lldb] Add a StackFrameRecognizer for the Darwin specific abort_with_payload… (PR #101365)

via lldb-commits lldb-commits at lists.llvm.org
Wed Jul 31 10:41:43 PDT 2024


https://github.com/jimingham updated https://github.com/llvm/llvm-project/pull/101365

>From 5b2cf0ab7e382e41ff3dfe88e4d7e35ddc99afd5 Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Tue, 30 Jul 2024 09:32:24 -0700
Subject: [PATCH 1/3] Add a StackFrameRecognizer for the Darwin specific
 abort_with_payload API.

---
 lldb/include/lldb/Target/Process.h            |  16 ++
 .../Platform/MacOSX/PlatformDarwin.cpp        |  45 ++--
 .../AbortWithPayloadFrameRecognizer.cpp       | 201 ++++++++++++++++++
 .../MacOSX/AbortWithPayloadFrameRecognizer.h  |  38 ++++
 .../SystemRuntime/MacOSX/CMakeLists.txt       |   1 +
 .../MacOSX/SystemRuntimeMacOSX.cpp            |   6 +-
 lldb/source/Target/Process.cpp                |   7 +-
 .../API/macosx/abort_with_payload/Makefile    |   4 +
 .../TestAbortWithPayload.py                   | 146 +++++++++++++
 .../test/API/macosx/abort_with_payload/main.c |  30 +++
 10 files changed, 478 insertions(+), 16 deletions(-)
 create mode 100644 lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.cpp
 create mode 100644 lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.h
 create mode 100644 lldb/test/API/macosx/abort_with_payload/Makefile
 create mode 100644 lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
 create mode 100644 lldb/test/API/macosx/abort_with_payload/main.c

diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index c8475db8ae160..ffff84bbd8a52 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2569,6 +2569,18 @@ void PruneThreadPlans();
   ///     A StructuredDataSP object which, if non-empty, will contain the
   ///     information related to the process.
   virtual StructuredData::DictionarySP GetMetadata() { return nullptr; }
+  
+  /// Fetch extended crash information held by the process.  This will never be
+  /// an empty shared pointer, it will always have a dict, though it may be
+  /// empty.
+  StructuredData::DictionarySP GetExtendedCrashInfoDict() {
+    return m_crash_info_dict_sp; 
+  }
+  
+  void ResetExtendedCrashInfoDict() {
+    // StructuredData::Dictionary is add only, so we have to make a new one:
+    m_crash_info_dict_sp.reset(new StructuredData::Dictionary());
+  }
 
   size_t AddImageToken(lldb::addr_t image_ptr);
 
@@ -3185,6 +3197,10 @@ void PruneThreadPlans();
 
   /// Per process source file cache.
   SourceManager::SourceFileCache m_source_file_cache;
+  
+  /// A repository for extra crash information, consulted in 
+  /// GetExtendedCrashInformation.
+  StructuredData::DictionarySP m_crash_info_dict_sp;
 
   size_t RemoveBreakpointOpcodesFromBuffer(lldb::addr_t addr, size_t size,
                                            uint8_t *buf) const;
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 6fb5bbfbe417b..398b44c293614 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -856,21 +856,38 @@ PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
 }
 
 llvm::Expected<StructuredData::DictionarySP>
-PlatformDarwin::FetchExtendedCrashInformation(Process &process) {
-  StructuredData::DictionarySP extended_crash_info =
-      std::make_shared<StructuredData::Dictionary>();
-
-  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);
+PlatformDarwin::
+FetchExtendedCrashInformation(Process &process) {
+  static constexpr llvm::StringLiteral crash_info_key("Crash-Info Annotations");
+  static constexpr llvm::StringLiteral asi_info_key("Application Specific Information");
+
+  // We cache the information we find in the process extended info dict:
+  StructuredData::DictionarySP process_dict_sp 
+      = process.GetExtendedCrashInfoDict();
+  StructuredData::Array *annotations = nullptr; 
+  StructuredData::ArraySP new_annotations_sp;
+  if (!process_dict_sp->GetValueForKeyAsArray(crash_info_key, annotations)) {
+    new_annotations_sp = ExtractCrashInfoAnnotations(process);
+    if (new_annotations_sp && new_annotations_sp->GetSize()) {
+      process_dict_sp->AddItem(crash_info_key, new_annotations_sp);
+      annotations = new_annotations_sp.get();
+    }
+  }
 
-  return extended_crash_info->GetSize() ? extended_crash_info : nullptr;
+  StructuredData::Dictionary *app_specific_info;
+  StructuredData::DictionarySP new_app_specific_info_sp;
+  if (!process_dict_sp->GetValueForKeyAsDictionary(asi_info_key, app_specific_info)) 
+  {
+    new_app_specific_info_sp = ExtractAppSpecificInfo(process);
+    if (new_app_specific_info_sp && new_app_specific_info_sp->GetSize()) {
+      process_dict_sp->AddItem(asi_info_key, new_app_specific_info_sp);
+      app_specific_info = new_app_specific_info_sp.get();
+    }
+  }
+  
+  // Now get anything else that was in the process info dict, and add it to the
+  // return here:
+  return process_dict_sp->GetSize() ? process_dict_sp : nullptr;
 }
 
 StructuredData::ArraySP
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.cpp
new file mode 100644
index 0000000000000..7f2aecd148379
--- /dev/null
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.cpp
@@ -0,0 +1,201 @@
+ //===-- AbortWithPayloadFrameRecognizer.cpp -------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "AbortWithPayloadFrameRecognizer.h"
+
+#include "lldb/Core/Value.h"
+#include "lldb/Core/ValueObjectConstResult.h"
+#include "lldb/Target/ABI.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrame.h"
+#include "lldb/Target/Target.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+#include "lldb/Utility/StructuredData.h"
+
+#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+namespace lldb_private {
+void RegisterAbortWithPayloadFrameRecognizer(Process *process) {
+  // There are two user-level API's that this recognizer captures, 
+  // abort_with_reason and abort_with_payload.  But they both call the private
+  // __abort_with_payload, the abort_with_reason call fills in a null payload.
+  static ConstString module_name("libsystem_kernel.dylib");
+  static ConstString sym_name("__abort_with_payload");
+  
+  if (!process)
+    return;
+  ConstString sym_arr[1]= {sym_name};
+  
+  process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
+        std::make_shared<AbortWithPayloadFrameRecognizer>(),
+        module_name, sym_arr,
+        /*first_instruction_only*/ false);
+}
+
+RecognizedStackFrameSP
+AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
+  // We have two jobs:
+  // 1) to add the data passed to abort_with_payload to the 
+  //    ExtraCrashInformation dictionary.
+  // 2) To make up faux arguments for this frame.
+  static constexpr llvm::StringLiteral namespace_key("namespace");
+  static constexpr llvm::StringLiteral code_key("code");
+  static constexpr llvm::StringLiteral payload_addr_key("payload_addr");
+  static constexpr llvm::StringLiteral payload_size_key("payload_size");
+  static constexpr llvm::StringLiteral reason_key("reason");
+  static constexpr llvm::StringLiteral flags_key("flags");
+  static constexpr llvm::StringLiteral info_key("abort_with_payload");
+    
+  // We are fetching the data from registers.
+  Thread *thread = frame_sp->GetThread().get();
+  Process *process = thread->GetProcess().get();
+
+  // FIXME: Add logging for these errors
+  if (!thread)
+    return {};
+
+  TypeSystemClangSP scratch_ts_sp =
+      ScratchTypeSystemClang::GetForTarget(process->GetTarget());
+  if (!scratch_ts_sp)
+    return {};
+
+    // The abort_with_payload signature is:
+    // abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, 
+    //                      void* payload, uint32_t payload_size, 
+    //                      const char* reason_string, uint64_t reason_flags);
+
+  ValueList arg_values;
+  Value input_value_32;
+  Value input_value_64;
+  Value input_value_void_ptr;
+  Value input_value_char_ptr;
+
+  CompilerType clang_void_ptr_type =
+      scratch_ts_sp->GetBasicType(eBasicTypeVoid).GetPointerType();
+  CompilerType clang_char_ptr_type =
+      scratch_ts_sp->GetBasicType(eBasicTypeChar).GetPointerType();
+  CompilerType clang_uint64_type =
+      scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint,
+                                                         64);
+  CompilerType clang_uint32_type =
+      scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint,
+                                                         32);
+  CompilerType clang_char_star_type =
+      scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint,
+                                                         64);
+  
+  input_value_32.SetValueType(Value::ValueType::Scalar);
+  input_value_32.SetCompilerType(clang_uint32_type);
+  input_value_64.SetValueType(Value::ValueType::Scalar);
+  input_value_64.SetCompilerType(clang_uint64_type);
+  input_value_void_ptr.SetValueType(Value::ValueType::Scalar);
+  input_value_void_ptr.SetCompilerType(clang_void_ptr_type);
+  input_value_char_ptr.SetValueType(Value::ValueType::Scalar);
+  input_value_char_ptr.SetCompilerType(clang_char_ptr_type);
+  
+  arg_values.PushValue(input_value_32);
+  arg_values.PushValue(input_value_64);
+  arg_values.PushValue(input_value_void_ptr);
+  arg_values.PushValue(input_value_32);
+  arg_values.PushValue(input_value_char_ptr);
+  arg_values.PushValue(input_value_64);
+
+  lldb::ABISP abi_sp = process->GetABI();
+  bool success = abi_sp->GetArgumentValues(*thread, arg_values);
+  if (!success)
+    return {};
+
+  Value *cur_value;
+  StackFrame *frame = frame_sp.get();
+  ValueObjectListSP arguments_sp = ValueObjectListSP(new ValueObjectList());
+
+  auto add_to_arguments = [&](llvm::StringRef name, Value *value, bool dynamic)
+  {
+    ValueObjectSP cur_valobj_sp = ValueObjectConstResult::Create(frame, *value,
+                                                 ConstString(name));
+    cur_valobj_sp = ValueObjectRecognizerSynthesizedValue::Create(
+        *cur_valobj_sp, eValueTypeVariableArgument);
+    ValueObjectSP dyn_valobj_sp;
+    if (dynamic) {
+      dyn_valobj_sp = cur_valobj_sp->GetDynamicValue(eDynamicDontRunTarget);
+      if (dyn_valobj_sp)
+        cur_valobj_sp = dyn_valobj_sp;
+    }
+    arguments_sp->Append(cur_valobj_sp);
+  };
+  
+  // Decode the arg_values:
+  
+  uint32_t namespace_val = 0;
+  cur_value = arg_values.GetValueAtIndex(0);
+  add_to_arguments(namespace_key, cur_value, false);
+  namespace_val = cur_value->GetScalar().UInt(namespace_val);
+  
+  uint32_t code_val = 0;
+  cur_value = arg_values.GetValueAtIndex(1);
+  add_to_arguments(code_key, cur_value, false);
+  code_val = cur_value->GetScalar().UInt(code_val);
+  
+  lldb::addr_t payload_addr = LLDB_INVALID_ADDRESS;
+  cur_value = arg_values.GetValueAtIndex(2);
+  add_to_arguments(payload_addr_key, cur_value, true);
+  payload_addr = cur_value->GetScalar().ULongLong(payload_addr);
+
+  uint32_t payload_size = 0;
+  cur_value = arg_values.GetValueAtIndex(3);
+  add_to_arguments(payload_size_key, cur_value, false);
+  payload_size = cur_value->GetScalar().UInt(payload_size);
+  
+  lldb::addr_t reason_addr = LLDB_INVALID_ADDRESS;
+  cur_value = arg_values.GetValueAtIndex(4);
+  add_to_arguments(reason_key, cur_value, false);
+  reason_addr = cur_value->GetScalar().ULongLong(payload_addr);
+  
+  // For the reason string, we want the string not the address, so fetch that.
+  std::string reason_string;
+  Status error;
+  size_t str_len = process->ReadCStringFromMemory(reason_addr, reason_string, error);
+  if (error.Fail())
+    return {};
+
+  uint32_t flags_val = 0;
+  cur_value = arg_values.GetValueAtIndex(5);
+  add_to_arguments(flags_key, cur_value, false);
+  flags_val = cur_value->GetScalar().UInt(flags_val);
+
+  // Okay, we've gotten all the argument values, now put then in a
+  // StructuredData, and add that to the Process ExtraCrashInformation:
+  StructuredData::DictionarySP abort_dict_sp(new StructuredData::Dictionary());
+  abort_dict_sp->AddIntegerItem(namespace_key, namespace_val);
+  abort_dict_sp->AddIntegerItem(code_key, code_val);
+  abort_dict_sp->AddIntegerItem(payload_addr_key, payload_addr);
+  abort_dict_sp->AddIntegerItem(payload_size_key, payload_size);
+  abort_dict_sp->AddStringItem(reason_key, reason_string);
+  abort_dict_sp->AddIntegerItem(flags_key, flags_val);
+
+  // This will overwrite any information in the dictionary already.  
+  // But we can only crash on abort_with_payload once, so that shouldn't matter.
+  process->GetExtendedCrashInfoDict()->AddItem(info_key, abort_dict_sp);
+  
+  return RecognizedStackFrameSP(new AbortWithPayloadRecognizedStackFrame(frame_sp, arguments_sp));  
+}
+
+AbortWithPayloadRecognizedStackFrame::AbortWithPayloadRecognizedStackFrame(
+    lldb::StackFrameSP &frame_sp, ValueObjectListSP &args_sp) : 
+        RecognizedStackFrame() {
+        m_arguments = args_sp;
+        m_stop_desc = "abort with payload or reason";
+}
+
+} // namespace lldb_private
+
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.h b/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.h
new file mode 100644
index 0000000000000..25053a4322e7d
--- /dev/null
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.h
@@ -0,0 +1,38 @@
+//===-- AbortWithPayloadFrameRecognizer.h -----------------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLDB_MACOSX_ABORTWITHPAYLOADFRAMERECOGNIZER_H
+#define LLDB_MACOSX_ABORTWITHPAYLOADFRAMERECOGNIZER_H
+
+#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrameRecognizer.h"
+#include "lldb/Utility/ConstString.h"
+#include "lldb/Utility/FileSpec.h"
+
+#include <tuple>
+
+namespace lldb_private {
+
+void RegisterAbortWithPayloadFrameRecognizer(Process *process);
+
+class AbortWithPayloadRecognizedStackFrame : public RecognizedStackFrame {
+public:
+  AbortWithPayloadRecognizedStackFrame(lldb::StackFrameSP &frame_sp, 
+                                       lldb::ValueObjectListSP &args_sp);
+};
+
+class AbortWithPayloadFrameRecognizer: public StackFrameRecognizer {
+ public:
+  std::string GetName() override { 
+      return "abort_with_payload StackFrame Recognizer"; }
+  lldb::RecognizedStackFrameSP
+    RecognizeFrame(lldb::StackFrameSP frame_sp) override;
+
+};
+} // namespace lldb_private
+
+#endif // LLDB_MACOSX_ABORTWITHPAYLOADFRAMERECOGNIZER_H
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt b/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt
index 04d30652ba4b4..17fccdf43c828 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/CMakeLists.txt
@@ -4,6 +4,7 @@ add_lldb_library(lldbPluginSystemRuntimeMacOSX PLUGIN
   AppleGetQueuesHandler.cpp
   AppleGetThreadItemInfoHandler.cpp
   SystemRuntimeMacOSX.cpp
+  AbortWithPayloadFrameRecognizer.cpp
 
   LINK_LIBS
     lldbBreakpoint
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 34ce175920d1e..999b81b49e6e0 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -29,6 +29,7 @@
 #include "lldb/Utility/StreamString.h"
 
 #include "SystemRuntimeMacOSX.h"
+#include "AbortWithPayloadFrameRecognizer.h"
 
 #include <memory>
 
@@ -90,7 +91,10 @@ SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
       m_libpthread_offsets(), m_dispatch_tsd_indexes_addr(LLDB_INVALID_ADDRESS),
       m_libdispatch_tsd_indexes(),
       m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
-      m_libdispatch_voucher_offsets() {}
+      m_libdispatch_voucher_offsets() {
+      
+  RegisterAbortWithPayloadFrameRecognizer(process);
+}
 
 // Destructor
 SystemRuntimeMacOSX::~SystemRuntimeMacOSX() { Clear(true); }
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index d5a639d9beacd..c72852d2afffa 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -477,7 +477,8 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
       m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false),
       m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false),
       m_can_interpret_function_calls(false), m_run_thread_plan_lock(),
-      m_can_jit(eCanJITDontKnow) {
+      m_can_jit(eCanJITDontKnow), 
+      m_crash_info_dict_sp(new StructuredData::Dictionary()) {
   CheckInWithManager();
 
   Log *log = GetLog(LLDBLog::Object);
@@ -3263,6 +3264,10 @@ Status Process::PrivateResume() {
   // If signals handing status changed we might want to update our signal
   // filters before resuming.
   UpdateAutomaticSignalFiltering();
+  // Clear any crash info we accumulated for this stop, but don't do so if we
+  // are running functions; we don't want to wipe out the real stop's info.
+  if (!GetModID().IsLastResumeForUserExpression())
+    ResetExtendedCrashInfoDict();
 
   Status error(WillResume());
   // Tell the process it is about to resume before the thread list
diff --git a/lldb/test/API/macosx/abort_with_payload/Makefile b/lldb/test/API/macosx/abort_with_payload/Makefile
new file mode 100644
index 0000000000000..695335e068c0c
--- /dev/null
+++ b/lldb/test/API/macosx/abort_with_payload/Makefile
@@ -0,0 +1,4 @@
+C_SOURCES := main.c
+CFLAGS_EXTRAS := -std=c99
+
+include Makefile.rules
diff --git a/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py b/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
new file mode 100644
index 0000000000000..764f8441382a5
--- /dev/null
+++ b/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
@@ -0,0 +1,146 @@
+"""
+Test that the FrameRecognizer for __abort_with_payload
+works properly
+"""
+
+
+import lldb
+import lldbsuite.test.lldbutil as lldbutil
+from lldbsuite.test.lldbtest import *
+
+
+class TestAbortWithPayload(TestBase):
+    NO_DEBUG_INFO_TESTCASE = True
+
+    def test_abort_with_payload(self):
+        """There can be many tests in a test case - describe this test here."""
+        self.build()
+        self.abort_with_test(True)
+
+    def test_abort_with_reason(self):
+        """There can be many tests in a test case - describe this test here."""
+        self.build()
+        self.abort_with_test(False)
+
+    def setUp(self):
+        # Call super's setUp().
+        TestBase.setUp(self)
+        self.main_source_file = lldb.SBFileSpec("main.c")
+
+    def abort_with_test(self, with_payload):
+        """If with_payload is True, we test the abort_with_payload call,
+           if false, we test abort_with_reason."""
+        launch_info = lldb.SBLaunchInfo([])
+        if not with_payload:
+            launch_info.SetArguments(["use_reason"], True)
+        (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
+            self, "Stop here before abort", self.main_source_file,
+            launch_info=launch_info
+        )
+
+        frame = thread.GetFrameAtIndex(0)
+        payload_str_var = frame.FindVariable("payload_string")
+        self.assertSuccess(payload_str_var.GetError(), "Got payload string var")
+        payload_var_addr = payload_str_var.unsigned
+        
+        payload_size_var = frame.FindVariable("payload_string_len")
+        self.assertSuccess(payload_size_var.GetError(), "Got payload string len var")
+        payload_size_val = payload_size_var.unsigned
+
+        # Not let it run to crash:
+        process.Continue()
+        
+        # At this point we should have stopped at the internal function.
+        # Make sure we selected the right thread:
+        sel_thread = process.GetSelectedThread()
+        self.assertEqual(thread, sel_thread, "Selected the original thread")
+        # Make sure the stop reason is right:
+        self.assertEqual(thread.GetStopDescription(100), "abort with payload or reason", "Description was right")
+        frame_0 = thread.frames[0]
+        self.assertEqual(frame_0.name, "__abort_with_payload", "Frame 0 was right")
+
+        # Now check the recognized argument values and the ExtendedCrashInformation version:
+        options = lldb.SBVariablesOptions()
+        options.SetIncludeRecognizedArguments(True)
+        options.SetIncludeArguments(False)
+        options.SetIncludeLocals(False)
+        options.SetIncludeStatics(False)
+        options.SetIncludeRuntimeSupportValues(False)
+
+        arguments = frame_0.GetVariables(options)
+
+        correct_values = { "namespace"       : 5,
+                           "code"            : 100,
+                           "payload_addr"    : payload_var_addr,
+                           "payload_size"    : payload_size_val,
+                           "payload_string"  : '"This is a payload that happens to be a string"',
+                           "reason_string"   : '"This is the reason string"',
+                           "reason_no_quote" : "This is the reason string",
+                           "flags": 0x85 }
+                           
+        # First check the recognized argument values: 
+        self.assertEqual(len(arguments), 6, "Got all six values")
+        self.runCmd("frame variable")
+        self.assertEqual(arguments[0].name, "namespace")
+        self.assertEqual(arguments[0].unsigned, correct_values["namespace"], "Namespace value correct")
+
+        self.assertEqual(arguments[1].name, "code")
+        self.assertEqual(arguments[1].unsigned, correct_values["code"], "code value correct")
+
+        # FIXME: I'm always adding these recognized arguments, but that looks wrong.  Should only
+        # add the payload ones if it is the payload not the reason function.
+        self.assertEqual(arguments[2].name, "payload_addr")
+        self.assertEqual(arguments[3].name, "payload_size")
+        if with_payload:
+            self.assertEqual(arguments[2].unsigned, correct_values["payload_addr"], "Payload matched variable address")
+            # We've made a payload that is a string, try to fetch that:
+            char_ptr_type = target.FindFirstType("char").GetPointerType()
+            self.assertTrue(char_ptr_type.IsValid(), "Got char ptr type")
+            
+            str_val = arguments[2].Cast(char_ptr_type)
+            self.assertEqual(str_val.summary, correct_values["payload_string"], "Got payload string")
+            
+            self.assertEqual(arguments[3].unsigned, correct_values["payload_size"], "payload size value correct")
+        else:
+            self.assertEqual(arguments[2].unsigned, 0, "Got 0 payload addr for reason call")
+            self.assertEqual(arguments[3].unsigned, 0, "Got 0 payload size for reason call")
+            
+        self.assertEqual(arguments[4].name, "reason")
+        self.assertEqual(arguments[4].summary, correct_values["reason_string"], "Reason value correct")
+
+        self.assertEqual(arguments[5].name, "flags")
+        self.assertEqual(arguments[5].unsigned, correct_values["flags"], "Flags value correct")
+
+        # Also check that the same info was stored in the ExtendedCrashInformation dict:
+        dict = process.GetExtendedCrashInformation()
+        self.assertTrue(dict.IsValid(), "Got extended crash information dict")
+        self.assertEqual(dict.GetType(), lldb.eStructuredDataTypeDictionary, "It is a dictionary")
+
+        abort_dict = dict.GetValueForKey("abort_with_payload")
+        self.assertTrue(abort_dict.IsValid(), "Got an abort_with_payload dict")
+        self.assertEqual(abort_dict.GetType(), lldb.eStructuredDataTypeDictionary, "It is a dictionary")
+
+        namespace_val = abort_dict.GetValueForKey("namespace")
+        self.assertTrue(namespace_val.IsValid(), "Got a valid namespace")
+        self.assertEqual(namespace_val.GetIntegerValue(0), correct_values["namespace"], "Namespace value correct")
+
+        code_val = abort_dict.GetValueForKey("code")
+        self.assertTrue(code_val.IsValid(), "Got a valid code")
+        self.assertEqual(code_val.GetIntegerValue(0), correct_values["code"], "Code value correct")
+
+        if with_payload:
+            addr_val = abort_dict.GetValueForKey("payload_addr")
+            self.assertTrue(addr_val.IsValid(), "Got a payload_addr")
+            self.assertEqual(addr_val.GetIntegerValue(0), correct_values["payload_addr"], "payload_addr right in dictionary")
+
+            size_val = abort_dict.GetValueForKey("payload_size")
+            self.assertTrue(size_val.IsValid(), "Got a payload size value")
+            self.assertEqual(size_val.GetIntegerValue(0), correct_values["payload_size"], "payload size right in dictionary")
+
+        reason_val = abort_dict.GetValueForKey("reason")
+        self.assertTrue(reason_val.IsValid(), "Got a reason key")
+        self.assertEqual(reason_val.GetStringValue(100), correct_values["reason_no_quote"], "reason right in dictionary")
+
+        flags_val = abort_dict.GetValueForKey("flags")
+        self.assertTrue(flags_val.IsValid(), "Got a flags value")
+        self.assertEqual(flags_val.GetIntegerValue(0), correct_values["flags"], "flags right in dictionary")
diff --git a/lldb/test/API/macosx/abort_with_payload/main.c b/lldb/test/API/macosx/abort_with_payload/main.c
new file mode 100644
index 0000000000000..aabe21b9cbbdf
--- /dev/null
+++ b/lldb/test/API/macosx/abort_with_payload/main.c
@@ -0,0 +1,30 @@
+// These defines are from bsd/sys/reason.h:
+#include <stdint.h>
+#include <string.h>
+
+extern void abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, void* payload, uint32_t payload_size, const char* reason_string, uint64_t reason_flags);
+
+extern void abort_with_reason(uint32_t reason_namespace, uint64_t reason_code, const char* reason_string, uint64_t reason_flags);
+
+#define OS_REASON_FLAG_FROM_USERSPACE           0x4
+#define OS_REASON_FLAG_NO_CRASH_REPORT          0x1
+#define OS_REASON_FLAG_ONE_TIME_FAILURE         0x80
+
+#define MY_REASON_FLAGS OS_REASON_FLAG_FROM_USERSPACE|OS_REASON_FLAG_NO_CRASH_REPORT|OS_REASON_FLAG_ONE_TIME_FAILURE
+#define OS_REASON_TEST          5
+
+int
+main(int argc, char **argv)
+{
+  const char *reason_string = "This is the reason string";
+  const char *payload_string  = "This is a payload that happens to be a string";
+  size_t payload_string_len = strlen(payload_string) + 1;
+  if (argc == 1) // Stop here before abort
+    abort_with_payload(OS_REASON_TEST, 100, (void *) payload_string , payload_string_len,
+                       reason_string, MY_REASON_FLAGS);
+ else
+    abort_with_reason(OS_REASON_TEST, 100, reason_string, MY_REASON_FLAGS);
+
+  return 0;
+
+}

>From 408882d0fec2f604418bf78dddb89962ffc27522 Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Wed, 31 Jul 2024 10:38:42 -0700
Subject: [PATCH 2/3] Mark the tests Darwin only.

---
 .../test/API/macosx/abort_with_payload/TestAbortWithPayload.py | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py b/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
index 764f8441382a5..b6bafc9e171ae 100644
--- a/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
+++ b/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
@@ -5,6 +5,7 @@
 
 
 import lldb
+from lldbsuite.test.decorators import *
 import lldbsuite.test.lldbutil as lldbutil
 from lldbsuite.test.lldbtest import *
 
@@ -12,11 +13,13 @@
 class TestAbortWithPayload(TestBase):
     NO_DEBUG_INFO_TESTCASE = True
 
+    @skipUnlessDarwin
     def test_abort_with_payload(self):
         """There can be many tests in a test case - describe this test here."""
         self.build()
         self.abort_with_test(True)
 
+    @skipUnlessDarwin
     def test_abort_with_reason(self):
         """There can be many tests in a test case - describe this test here."""
         self.build()

>From 9c5b9160a600d40e26830e8a9111f90ffc64052c Mon Sep 17 00:00:00 2001
From: Jim Ingham <jingham at apple.com>
Date: Wed, 31 Jul 2024 10:41:24 -0700
Subject: [PATCH 3/3] formatting

---
 lldb/include/lldb/Target/Process.h            |  10 +-
 .../Platform/MacOSX/PlatformDarwin.cpp        |  18 +--
 .../AbortWithPayloadFrameRecognizer.cpp       |  70 ++++-----
 .../MacOSX/AbortWithPayloadFrameRecognizer.h  |  14 +-
 .../MacOSX/SystemRuntimeMacOSX.cpp            |   4 +-
 lldb/source/Target/Process.cpp                |   2 +-
 .../TestAbortWithPayload.py                   | 134 +++++++++++++-----
 .../test/API/macosx/abort_with_payload/main.c |  33 +++--
 8 files changed, 175 insertions(+), 110 deletions(-)

diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index ffff84bbd8a52..e1be76d494b1f 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -2569,14 +2569,14 @@ void PruneThreadPlans();
   ///     A StructuredDataSP object which, if non-empty, will contain the
   ///     information related to the process.
   virtual StructuredData::DictionarySP GetMetadata() { return nullptr; }
-  
+
   /// Fetch extended crash information held by the process.  This will never be
   /// an empty shared pointer, it will always have a dict, though it may be
   /// empty.
   StructuredData::DictionarySP GetExtendedCrashInfoDict() {
-    return m_crash_info_dict_sp; 
+    return m_crash_info_dict_sp;
   }
-  
+
   void ResetExtendedCrashInfoDict() {
     // StructuredData::Dictionary is add only, so we have to make a new one:
     m_crash_info_dict_sp.reset(new StructuredData::Dictionary());
@@ -3197,8 +3197,8 @@ void PruneThreadPlans();
 
   /// Per process source file cache.
   SourceManager::SourceFileCache m_source_file_cache;
-  
-  /// A repository for extra crash information, consulted in 
+
+  /// A repository for extra crash information, consulted in
   /// GetExtendedCrashInformation.
   StructuredData::DictionarySP m_crash_info_dict_sp;
 
diff --git a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
index 398b44c293614..3d22e7122d472 100644
--- a/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
+++ b/lldb/source/Plugins/Platform/MacOSX/PlatformDarwin.cpp
@@ -856,15 +856,15 @@ PlatformDarwin::ParseVersionBuildDir(llvm::StringRef dir) {
 }
 
 llvm::Expected<StructuredData::DictionarySP>
-PlatformDarwin::
-FetchExtendedCrashInformation(Process &process) {
+PlatformDarwin::FetchExtendedCrashInformation(Process &process) {
   static constexpr llvm::StringLiteral crash_info_key("Crash-Info Annotations");
-  static constexpr llvm::StringLiteral asi_info_key("Application Specific Information");
+  static constexpr llvm::StringLiteral asi_info_key(
+      "Application Specific Information");
 
   // We cache the information we find in the process extended info dict:
-  StructuredData::DictionarySP process_dict_sp 
-      = process.GetExtendedCrashInfoDict();
-  StructuredData::Array *annotations = nullptr; 
+  StructuredData::DictionarySP process_dict_sp =
+      process.GetExtendedCrashInfoDict();
+  StructuredData::Array *annotations = nullptr;
   StructuredData::ArraySP new_annotations_sp;
   if (!process_dict_sp->GetValueForKeyAsArray(crash_info_key, annotations)) {
     new_annotations_sp = ExtractCrashInfoAnnotations(process);
@@ -876,15 +876,15 @@ FetchExtendedCrashInformation(Process &process) {
 
   StructuredData::Dictionary *app_specific_info;
   StructuredData::DictionarySP new_app_specific_info_sp;
-  if (!process_dict_sp->GetValueForKeyAsDictionary(asi_info_key, app_specific_info)) 
-  {
+  if (!process_dict_sp->GetValueForKeyAsDictionary(asi_info_key,
+                                                   app_specific_info)) {
     new_app_specific_info_sp = ExtractAppSpecificInfo(process);
     if (new_app_specific_info_sp && new_app_specific_info_sp->GetSize()) {
       process_dict_sp->AddItem(asi_info_key, new_app_specific_info_sp);
       app_specific_info = new_app_specific_info_sp.get();
     }
   }
-  
+
   // Now get anything else that was in the process info dict, and add it to the
   // return here:
   return process_dict_sp->GetSize() ? process_dict_sp : nullptr;
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.cpp
index 7f2aecd148379..5434601f54401 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.cpp
@@ -1,4 +1,4 @@
- //===-- AbortWithPayloadFrameRecognizer.cpp -------------------------------===//
+//===-- AbortWithPayloadFrameRecognizer.cpp -------------------------------===//
 //
 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 // See https://llvm.org/LICENSE.txt for license information.
@@ -26,26 +26,25 @@ using namespace lldb_private;
 
 namespace lldb_private {
 void RegisterAbortWithPayloadFrameRecognizer(Process *process) {
-  // There are two user-level API's that this recognizer captures, 
+  // There are two user-level API's that this recognizer captures,
   // abort_with_reason and abort_with_payload.  But they both call the private
   // __abort_with_payload, the abort_with_reason call fills in a null payload.
   static ConstString module_name("libsystem_kernel.dylib");
   static ConstString sym_name("__abort_with_payload");
-  
+
   if (!process)
     return;
-  ConstString sym_arr[1]= {sym_name};
-  
+  ConstString sym_arr[1] = {sym_name};
+
   process->GetTarget().GetFrameRecognizerManager().AddRecognizer(
-        std::make_shared<AbortWithPayloadFrameRecognizer>(),
-        module_name, sym_arr,
-        /*first_instruction_only*/ false);
+      std::make_shared<AbortWithPayloadFrameRecognizer>(), module_name, sym_arr,
+      /*first_instruction_only*/ false);
 }
 
 RecognizedStackFrameSP
 AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   // We have two jobs:
-  // 1) to add the data passed to abort_with_payload to the 
+  // 1) to add the data passed to abort_with_payload to the
   //    ExtraCrashInformation dictionary.
   // 2) To make up faux arguments for this frame.
   static constexpr llvm::StringLiteral namespace_key("namespace");
@@ -55,7 +54,7 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   static constexpr llvm::StringLiteral reason_key("reason");
   static constexpr llvm::StringLiteral flags_key("flags");
   static constexpr llvm::StringLiteral info_key("abort_with_payload");
-    
+
   // We are fetching the data from registers.
   Thread *thread = frame_sp->GetThread().get();
   Process *process = thread->GetProcess().get();
@@ -69,10 +68,10 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   if (!scratch_ts_sp)
     return {};
 
-    // The abort_with_payload signature is:
-    // abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, 
-    //                      void* payload, uint32_t payload_size, 
-    //                      const char* reason_string, uint64_t reason_flags);
+  // The abort_with_payload signature is:
+  // abort_with_payload(uint32_t reason_namespace, uint64_t reason_code,
+  //                      void* payload, uint32_t payload_size,
+  //                      const char* reason_string, uint64_t reason_flags);
 
   ValueList arg_values;
   Value input_value_32;
@@ -93,7 +92,7 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   CompilerType clang_char_star_type =
       scratch_ts_sp->GetBuiltinTypeForEncodingAndBitSize(lldb::eEncodingUint,
                                                          64);
-  
+
   input_value_32.SetValueType(Value::ValueType::Scalar);
   input_value_32.SetCompilerType(clang_uint32_type);
   input_value_64.SetValueType(Value::ValueType::Scalar);
@@ -102,7 +101,7 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   input_value_void_ptr.SetCompilerType(clang_void_ptr_type);
   input_value_char_ptr.SetValueType(Value::ValueType::Scalar);
   input_value_char_ptr.SetCompilerType(clang_char_ptr_type);
-  
+
   arg_values.PushValue(input_value_32);
   arg_values.PushValue(input_value_64);
   arg_values.PushValue(input_value_void_ptr);
@@ -119,10 +118,10 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   StackFrame *frame = frame_sp.get();
   ValueObjectListSP arguments_sp = ValueObjectListSP(new ValueObjectList());
 
-  auto add_to_arguments = [&](llvm::StringRef name, Value *value, bool dynamic)
-  {
-    ValueObjectSP cur_valobj_sp = ValueObjectConstResult::Create(frame, *value,
-                                                 ConstString(name));
+  auto add_to_arguments = [&](llvm::StringRef name, Value *value,
+                              bool dynamic) {
+    ValueObjectSP cur_valobj_sp =
+        ValueObjectConstResult::Create(frame, *value, ConstString(name));
     cur_valobj_sp = ValueObjectRecognizerSynthesizedValue::Create(
         *cur_valobj_sp, eValueTypeVariableArgument);
     ValueObjectSP dyn_valobj_sp;
@@ -133,19 +132,19 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
     }
     arguments_sp->Append(cur_valobj_sp);
   };
-  
+
   // Decode the arg_values:
-  
+
   uint32_t namespace_val = 0;
   cur_value = arg_values.GetValueAtIndex(0);
   add_to_arguments(namespace_key, cur_value, false);
   namespace_val = cur_value->GetScalar().UInt(namespace_val);
-  
+
   uint32_t code_val = 0;
   cur_value = arg_values.GetValueAtIndex(1);
   add_to_arguments(code_key, cur_value, false);
   code_val = cur_value->GetScalar().UInt(code_val);
-  
+
   lldb::addr_t payload_addr = LLDB_INVALID_ADDRESS;
   cur_value = arg_values.GetValueAtIndex(2);
   add_to_arguments(payload_addr_key, cur_value, true);
@@ -155,16 +154,17 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   cur_value = arg_values.GetValueAtIndex(3);
   add_to_arguments(payload_size_key, cur_value, false);
   payload_size = cur_value->GetScalar().UInt(payload_size);
-  
+
   lldb::addr_t reason_addr = LLDB_INVALID_ADDRESS;
   cur_value = arg_values.GetValueAtIndex(4);
   add_to_arguments(reason_key, cur_value, false);
   reason_addr = cur_value->GetScalar().ULongLong(payload_addr);
-  
+
   // For the reason string, we want the string not the address, so fetch that.
   std::string reason_string;
   Status error;
-  size_t str_len = process->ReadCStringFromMemory(reason_addr, reason_string, error);
+  size_t str_len =
+      process->ReadCStringFromMemory(reason_addr, reason_string, error);
   if (error.Fail())
     return {};
 
@@ -183,19 +183,19 @@ AbortWithPayloadFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   abort_dict_sp->AddStringItem(reason_key, reason_string);
   abort_dict_sp->AddIntegerItem(flags_key, flags_val);
 
-  // This will overwrite any information in the dictionary already.  
+  // This will overwrite any information in the dictionary already.
   // But we can only crash on abort_with_payload once, so that shouldn't matter.
   process->GetExtendedCrashInfoDict()->AddItem(info_key, abort_dict_sp);
-  
-  return RecognizedStackFrameSP(new AbortWithPayloadRecognizedStackFrame(frame_sp, arguments_sp));  
+
+  return RecognizedStackFrameSP(
+      new AbortWithPayloadRecognizedStackFrame(frame_sp, arguments_sp));
 }
 
 AbortWithPayloadRecognizedStackFrame::AbortWithPayloadRecognizedStackFrame(
-    lldb::StackFrameSP &frame_sp, ValueObjectListSP &args_sp) : 
-        RecognizedStackFrame() {
-        m_arguments = args_sp;
-        m_stop_desc = "abort with payload or reason";
+    lldb::StackFrameSP &frame_sp, ValueObjectListSP &args_sp)
+    : RecognizedStackFrame() {
+  m_arguments = args_sp;
+  m_stop_desc = "abort with payload or reason";
 }
 
 } // namespace lldb_private
-
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.h b/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.h
index 25053a4322e7d..6f3538647aadf 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.h
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/AbortWithPayloadFrameRecognizer.h
@@ -21,17 +21,17 @@ void RegisterAbortWithPayloadFrameRecognizer(Process *process);
 
 class AbortWithPayloadRecognizedStackFrame : public RecognizedStackFrame {
 public:
-  AbortWithPayloadRecognizedStackFrame(lldb::StackFrameSP &frame_sp, 
+  AbortWithPayloadRecognizedStackFrame(lldb::StackFrameSP &frame_sp,
                                        lldb::ValueObjectListSP &args_sp);
 };
 
-class AbortWithPayloadFrameRecognizer: public StackFrameRecognizer {
- public:
-  std::string GetName() override { 
-      return "abort_with_payload StackFrame Recognizer"; }
+class AbortWithPayloadFrameRecognizer : public StackFrameRecognizer {
+public:
+  std::string GetName() override {
+    return "abort_with_payload StackFrame Recognizer";
+  }
   lldb::RecognizedStackFrameSP
-    RecognizeFrame(lldb::StackFrameSP frame_sp) override;
-
+  RecognizeFrame(lldb::StackFrameSP frame_sp) override;
 };
 } // namespace lldb_private
 
diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
index 999b81b49e6e0..0556b87777884 100644
--- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
+++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp
@@ -28,8 +28,8 @@
 #include "lldb/Utility/Log.h"
 #include "lldb/Utility/StreamString.h"
 
-#include "SystemRuntimeMacOSX.h"
 #include "AbortWithPayloadFrameRecognizer.h"
+#include "SystemRuntimeMacOSX.h"
 
 #include <memory>
 
@@ -92,7 +92,7 @@ SystemRuntimeMacOSX::SystemRuntimeMacOSX(Process *process)
       m_libdispatch_tsd_indexes(),
       m_dispatch_voucher_offsets_addr(LLDB_INVALID_ADDRESS),
       m_libdispatch_voucher_offsets() {
-      
+
   RegisterAbortWithPayloadFrameRecognizer(process);
 }
 
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index c72852d2afffa..728f9aadef779 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -477,7 +477,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP listener_sp,
       m_clear_thread_plans_on_stop(false), m_force_next_event_delivery(false),
       m_last_broadcast_state(eStateInvalid), m_destroy_in_process(false),
       m_can_interpret_function_calls(false), m_run_thread_plan_lock(),
-      m_can_jit(eCanJITDontKnow), 
+      m_can_jit(eCanJITDontKnow),
       m_crash_info_dict_sp(new StructuredData::Dictionary()) {
   CheckInWithManager();
 
diff --git a/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py b/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
index b6bafc9e171ae..5934e23237053 100644
--- a/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
+++ b/lldb/test/API/macosx/abort_with_payload/TestAbortWithPayload.py
@@ -32,33 +32,39 @@ def setUp(self):
 
     def abort_with_test(self, with_payload):
         """If with_payload is True, we test the abort_with_payload call,
-           if false, we test abort_with_reason."""
+        if false, we test abort_with_reason."""
         launch_info = lldb.SBLaunchInfo([])
         if not with_payload:
             launch_info.SetArguments(["use_reason"], True)
         (target, process, thread, bkpt) = lldbutil.run_to_source_breakpoint(
-            self, "Stop here before abort", self.main_source_file,
-            launch_info=launch_info
+            self,
+            "Stop here before abort",
+            self.main_source_file,
+            launch_info=launch_info,
         )
 
         frame = thread.GetFrameAtIndex(0)
         payload_str_var = frame.FindVariable("payload_string")
         self.assertSuccess(payload_str_var.GetError(), "Got payload string var")
         payload_var_addr = payload_str_var.unsigned
-        
+
         payload_size_var = frame.FindVariable("payload_string_len")
         self.assertSuccess(payload_size_var.GetError(), "Got payload string len var")
         payload_size_val = payload_size_var.unsigned
 
         # Not let it run to crash:
         process.Continue()
-        
+
         # At this point we should have stopped at the internal function.
         # Make sure we selected the right thread:
         sel_thread = process.GetSelectedThread()
         self.assertEqual(thread, sel_thread, "Selected the original thread")
         # Make sure the stop reason is right:
-        self.assertEqual(thread.GetStopDescription(100), "abort with payload or reason", "Description was right")
+        self.assertEqual(
+            thread.GetStopDescription(100),
+            "abort with payload or reason",
+            "Description was right",
+        )
         frame_0 = thread.frames[0]
         self.assertEqual(frame_0.name, "__abort_with_payload", "Frame 0 was right")
 
@@ -72,78 +78,134 @@ def abort_with_test(self, with_payload):
 
         arguments = frame_0.GetVariables(options)
 
-        correct_values = { "namespace"       : 5,
-                           "code"            : 100,
-                           "payload_addr"    : payload_var_addr,
-                           "payload_size"    : payload_size_val,
-                           "payload_string"  : '"This is a payload that happens to be a string"',
-                           "reason_string"   : '"This is the reason string"',
-                           "reason_no_quote" : "This is the reason string",
-                           "flags": 0x85 }
-                           
-        # First check the recognized argument values: 
+        correct_values = {
+            "namespace": 5,
+            "code": 100,
+            "payload_addr": payload_var_addr,
+            "payload_size": payload_size_val,
+            "payload_string": '"This is a payload that happens to be a string"',
+            "reason_string": '"This is the reason string"',
+            "reason_no_quote": "This is the reason string",
+            "flags": 0x85,
+        }
+
+        # First check the recognized argument values:
         self.assertEqual(len(arguments), 6, "Got all six values")
         self.runCmd("frame variable")
         self.assertEqual(arguments[0].name, "namespace")
-        self.assertEqual(arguments[0].unsigned, correct_values["namespace"], "Namespace value correct")
+        self.assertEqual(
+            arguments[0].unsigned,
+            correct_values["namespace"],
+            "Namespace value correct",
+        )
 
         self.assertEqual(arguments[1].name, "code")
-        self.assertEqual(arguments[1].unsigned, correct_values["code"], "code value correct")
+        self.assertEqual(
+            arguments[1].unsigned, correct_values["code"], "code value correct"
+        )
 
         # FIXME: I'm always adding these recognized arguments, but that looks wrong.  Should only
         # add the payload ones if it is the payload not the reason function.
         self.assertEqual(arguments[2].name, "payload_addr")
         self.assertEqual(arguments[3].name, "payload_size")
         if with_payload:
-            self.assertEqual(arguments[2].unsigned, correct_values["payload_addr"], "Payload matched variable address")
+            self.assertEqual(
+                arguments[2].unsigned,
+                correct_values["payload_addr"],
+                "Payload matched variable address",
+            )
             # We've made a payload that is a string, try to fetch that:
             char_ptr_type = target.FindFirstType("char").GetPointerType()
             self.assertTrue(char_ptr_type.IsValid(), "Got char ptr type")
-            
+
             str_val = arguments[2].Cast(char_ptr_type)
-            self.assertEqual(str_val.summary, correct_values["payload_string"], "Got payload string")
-            
-            self.assertEqual(arguments[3].unsigned, correct_values["payload_size"], "payload size value correct")
+            self.assertEqual(
+                str_val.summary, correct_values["payload_string"], "Got payload string"
+            )
+
+            self.assertEqual(
+                arguments[3].unsigned,
+                correct_values["payload_size"],
+                "payload size value correct",
+            )
         else:
-            self.assertEqual(arguments[2].unsigned, 0, "Got 0 payload addr for reason call")
-            self.assertEqual(arguments[3].unsigned, 0, "Got 0 payload size for reason call")
-            
+            self.assertEqual(
+                arguments[2].unsigned, 0, "Got 0 payload addr for reason call"
+            )
+            self.assertEqual(
+                arguments[3].unsigned, 0, "Got 0 payload size for reason call"
+            )
+
         self.assertEqual(arguments[4].name, "reason")
-        self.assertEqual(arguments[4].summary, correct_values["reason_string"], "Reason value correct")
+        self.assertEqual(
+            arguments[4].summary,
+            correct_values["reason_string"],
+            "Reason value correct",
+        )
 
         self.assertEqual(arguments[5].name, "flags")
-        self.assertEqual(arguments[5].unsigned, correct_values["flags"], "Flags value correct")
+        self.assertEqual(
+            arguments[5].unsigned, correct_values["flags"], "Flags value correct"
+        )
 
         # Also check that the same info was stored in the ExtendedCrashInformation dict:
         dict = process.GetExtendedCrashInformation()
         self.assertTrue(dict.IsValid(), "Got extended crash information dict")
-        self.assertEqual(dict.GetType(), lldb.eStructuredDataTypeDictionary, "It is a dictionary")
+        self.assertEqual(
+            dict.GetType(), lldb.eStructuredDataTypeDictionary, "It is a dictionary"
+        )
 
         abort_dict = dict.GetValueForKey("abort_with_payload")
         self.assertTrue(abort_dict.IsValid(), "Got an abort_with_payload dict")
-        self.assertEqual(abort_dict.GetType(), lldb.eStructuredDataTypeDictionary, "It is a dictionary")
+        self.assertEqual(
+            abort_dict.GetType(),
+            lldb.eStructuredDataTypeDictionary,
+            "It is a dictionary",
+        )
 
         namespace_val = abort_dict.GetValueForKey("namespace")
         self.assertTrue(namespace_val.IsValid(), "Got a valid namespace")
-        self.assertEqual(namespace_val.GetIntegerValue(0), correct_values["namespace"], "Namespace value correct")
+        self.assertEqual(
+            namespace_val.GetIntegerValue(0),
+            correct_values["namespace"],
+            "Namespace value correct",
+        )
 
         code_val = abort_dict.GetValueForKey("code")
         self.assertTrue(code_val.IsValid(), "Got a valid code")
-        self.assertEqual(code_val.GetIntegerValue(0), correct_values["code"], "Code value correct")
+        self.assertEqual(
+            code_val.GetIntegerValue(0), correct_values["code"], "Code value correct"
+        )
 
         if with_payload:
             addr_val = abort_dict.GetValueForKey("payload_addr")
             self.assertTrue(addr_val.IsValid(), "Got a payload_addr")
-            self.assertEqual(addr_val.GetIntegerValue(0), correct_values["payload_addr"], "payload_addr right in dictionary")
+            self.assertEqual(
+                addr_val.GetIntegerValue(0),
+                correct_values["payload_addr"],
+                "payload_addr right in dictionary",
+            )
 
             size_val = abort_dict.GetValueForKey("payload_size")
             self.assertTrue(size_val.IsValid(), "Got a payload size value")
-            self.assertEqual(size_val.GetIntegerValue(0), correct_values["payload_size"], "payload size right in dictionary")
+            self.assertEqual(
+                size_val.GetIntegerValue(0),
+                correct_values["payload_size"],
+                "payload size right in dictionary",
+            )
 
         reason_val = abort_dict.GetValueForKey("reason")
         self.assertTrue(reason_val.IsValid(), "Got a reason key")
-        self.assertEqual(reason_val.GetStringValue(100), correct_values["reason_no_quote"], "reason right in dictionary")
+        self.assertEqual(
+            reason_val.GetStringValue(100),
+            correct_values["reason_no_quote"],
+            "reason right in dictionary",
+        )
 
         flags_val = abort_dict.GetValueForKey("flags")
         self.assertTrue(flags_val.IsValid(), "Got a flags value")
-        self.assertEqual(flags_val.GetIntegerValue(0), correct_values["flags"], "flags right in dictionary")
+        self.assertEqual(
+            flags_val.GetIntegerValue(0),
+            correct_values["flags"],
+            "flags right in dictionary",
+        )
diff --git a/lldb/test/API/macosx/abort_with_payload/main.c b/lldb/test/API/macosx/abort_with_payload/main.c
index aabe21b9cbbdf..a10a6cf65fe69 100644
--- a/lldb/test/API/macosx/abort_with_payload/main.c
+++ b/lldb/test/API/macosx/abort_with_payload/main.c
@@ -2,29 +2,32 @@
 #include <stdint.h>
 #include <string.h>
 
-extern void abort_with_payload(uint32_t reason_namespace, uint64_t reason_code, void* payload, uint32_t payload_size, const char* reason_string, uint64_t reason_flags);
+extern void abort_with_payload(uint32_t reason_namespace, uint64_t reason_code,
+                               void *payload, uint32_t payload_size,
+                               const char *reason_string,
+                               uint64_t reason_flags);
 
-extern void abort_with_reason(uint32_t reason_namespace, uint64_t reason_code, const char* reason_string, uint64_t reason_flags);
+extern void abort_with_reason(uint32_t reason_namespace, uint64_t reason_code,
+                              const char *reason_string, uint64_t reason_flags);
 
-#define OS_REASON_FLAG_FROM_USERSPACE           0x4
-#define OS_REASON_FLAG_NO_CRASH_REPORT          0x1
-#define OS_REASON_FLAG_ONE_TIME_FAILURE         0x80
+#define OS_REASON_FLAG_FROM_USERSPACE 0x4
+#define OS_REASON_FLAG_NO_CRASH_REPORT 0x1
+#define OS_REASON_FLAG_ONE_TIME_FAILURE 0x80
 
-#define MY_REASON_FLAGS OS_REASON_FLAG_FROM_USERSPACE|OS_REASON_FLAG_NO_CRASH_REPORT|OS_REASON_FLAG_ONE_TIME_FAILURE
-#define OS_REASON_TEST          5
+#define MY_REASON_FLAGS                                                        \
+  OS_REASON_FLAG_FROM_USERSPACE | OS_REASON_FLAG_NO_CRASH_REPORT |             \
+      OS_REASON_FLAG_ONE_TIME_FAILURE
+#define OS_REASON_TEST 5
 
-int
-main(int argc, char **argv)
-{
+int main(int argc, char **argv) {
   const char *reason_string = "This is the reason string";
-  const char *payload_string  = "This is a payload that happens to be a string";
+  const char *payload_string = "This is a payload that happens to be a string";
   size_t payload_string_len = strlen(payload_string) + 1;
   if (argc == 1) // Stop here before abort
-    abort_with_payload(OS_REASON_TEST, 100, (void *) payload_string , payload_string_len,
-                       reason_string, MY_REASON_FLAGS);
- else
+    abort_with_payload(OS_REASON_TEST, 100, (void *)payload_string,
+                       payload_string_len, reason_string, MY_REASON_FLAGS);
+  else
     abort_with_reason(OS_REASON_TEST, 100, reason_string, MY_REASON_FLAGS);
 
   return 0;
-
 }



More information about the lldb-commits mailing list