https://github.com/Michael137 updated 
https://github.com/llvm/llvm-project/pull/80368

>From 4ffcb261af05b2a68781cf353d8e45bf921f8cb7 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Thu, 25 Jan 2024 11:05:02 +0000
Subject: [PATCH 1/6] [lldb] Add frame recognizer for __builtin_verbose_trap

This patch adds a frame recognizer for Clang's
`__builtin_verbose_trap`, which behaves like a
`__builtin_trap`, but emits a failure-reason string
into debug-info in order for debuggers to display
it to a user.

The frame recognizer triggers when we encounter
a frame with a function name that begins with
`__llvm_verbose_trap`, which is the magic prefix
Clang emits into debug-info for verbose traps.
Once such frame is encountered we display the
frame function name as the `Stop Reason` and display
that frame to the user.

Example output:
```
(lldb) run
warning: a.out was compiled with optimization - stepping may behave oddly; 
variables may not be available.
Process 35942 launched: 'a.out' (arm64)
Process 35942 stopped
* thread #1, queue = 'com.apple.main-thread', stop reason = 
__llvm_verbose_trap: Function is not implemented
    frame #1: 0x0000000100003fa4 a.out`main [inlined] 
Dummy::func(this=<unavailable>) at verbose_trap.cpp:3:5 [opt]
   1    struct Dummy {
   2      void func() {
-> 3        __builtin_verbose_trap("Function is not implemented");
   4      }
   5    };
   6
   7    int main() {
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = 
__llvm_verbose_trap: Function is not implemented
    frame #0: 0x0000000100003fa4 a.out`main [inlined] __llvm_verbose_trap: 
Function is not implemented at verbose_trap.cpp:0 [opt]
  * frame #1: 0x0000000100003fa4 a.out`main [inlined] 
Dummy::func(this=<unavailable>) at verbose_trap.cpp:3:5 [opt]
    frame #2: 0x0000000100003fa4 a.out`main at verbose_trap.cpp:8:13 [opt]
    frame #3: 0x0000000189d518b4 dyld`start + 1988
```
---
 .../lldb/Target/VerboseTrapFrameRecognizer.h  | 39 +++++++++
 lldb/source/Target/CMakeLists.txt             |  1 +
 lldb/source/Target/Process.cpp                |  2 +
 .../Target/VerboseTrapFrameRecognizer.cpp     | 85 +++++++++++++++++++
 .../Shell/Recognizer/Inputs/verbose_trap.cpp  |  8 ++
 lldb/test/Shell/Recognizer/verbose_trap.test  |  9 ++
 6 files changed, 144 insertions(+)
 create mode 100644 lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h
 create mode 100644 lldb/source/Target/VerboseTrapFrameRecognizer.cpp
 create mode 100644 lldb/test/Shell/Recognizer/Inputs/verbose_trap.cpp
 create mode 100644 lldb/test/Shell/Recognizer/verbose_trap.test

diff --git a/lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h 
b/lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h
new file mode 100644
index 00000000000000..7e045760a28be6
--- /dev/null
+++ b/lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h
@@ -0,0 +1,39 @@
+#ifndef LLDB_TARGET_VERBOSETRAPFRAMERECOGNIZER_H
+#define LLDB_TARGET_VERBOSETRAPFRAMERECOGNIZER_H
+
+#include "lldb/Target/StackFrameRecognizer.h"
+
+namespace lldb_private {
+
+void RegisterVerboseTrapFrameRecognizer(Process &process);
+
+/// Holds the stack frame that caused the Verbose trap and the inlined stop
+/// reason message.
+class VerboseTrapRecognizedStackFrame : public RecognizedStackFrame {
+public:
+  VerboseTrapRecognizedStackFrame(lldb::StackFrameSP most_relevant_frame_sp,
+                                  std::string stop_desc);
+
+  lldb::StackFrameSP GetMostRelevantFrame() override;
+
+private:
+  lldb::StackFrameSP m_most_relevant_frame;
+};
+
+/// When a thread stops, it checks the current frame contains a
+/// Verbose Trap diagnostic. If so, it returns a \a
+/// VerboseTrapRecognizedStackFrame holding the diagnostic a stop reason
+/// description with and the parent frame as the most relavant frame.
+class VerboseTrapFrameRecognizer : public StackFrameRecognizer {
+public:
+  std::string GetName() override {
+    return "Verbose Trap StackFrame Recognizer";
+  }
+
+  lldb::RecognizedStackFrameSP
+  RecognizeFrame(lldb::StackFrameSP frame) override;
+};
+
+} // namespace lldb_private
+
+#endif // LLDB_TARGET_VERBOSETRAPFRAMERECOGNIZER_H
diff --git a/lldb/source/Target/CMakeLists.txt 
b/lldb/source/Target/CMakeLists.txt
index cf4818eae3eb8b..8186ccbea27d42 100644
--- a/lldb/source/Target/CMakeLists.txt
+++ b/lldb/source/Target/CMakeLists.txt
@@ -78,6 +78,7 @@ add_lldb_library(lldbTarget
   UnixSignals.cpp
   UnwindAssembly.cpp
   UnwindLLDB.cpp
+  VerboseTrapFrameRecognizer.cpp
 
   LINK_LIBS
     lldbBreakpoint
diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp
index 6d58873b54a3ad..cd9b48248e4bd9 100644
--- a/lldb/source/Target/Process.cpp
+++ b/lldb/source/Target/Process.cpp
@@ -63,6 +63,7 @@
 #include "lldb/Target/ThreadPlanCallFunction.h"
 #include "lldb/Target/ThreadPlanStack.h"
 #include "lldb/Target/UnixSignals.h"
+#include "lldb/Target/VerboseTrapFrameRecognizer.h"
 #include "lldb/Utility/Event.h"
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
@@ -497,6 +498,7 @@ Process::Process(lldb::TargetSP target_sp, ListenerSP 
listener_sp,
     value_sp->SetValueAs(platform_cache_line_size);
 
   RegisterAssertFrameRecognizer(this);
+  RegisterVerboseTrapFrameRecognizer(*this);
 }
 
 Process::~Process() {
diff --git a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp 
b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
new file mode 100644
index 00000000000000..d1a9ec18f8fe44
--- /dev/null
+++ b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
@@ -0,0 +1,85 @@
+#include "lldb/Target/VerboseTrapFrameRecognizer.h"
+
+#include "lldb/Core/Module.h"
+#include "lldb/Symbol/Function.h"
+#include "lldb/Symbol/SymbolContext.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Target/Target.h"
+
+#include "lldb/Utility/LLDBLog.h"
+#include "lldb/Utility/Log.h"
+
+using namespace llvm;
+using namespace lldb;
+using namespace lldb_private;
+
+VerboseTrapRecognizedStackFrame::VerboseTrapRecognizedStackFrame(
+    StackFrameSP most_relevant_frame_sp, std::string stop_desc)
+    : m_most_relevant_frame(most_relevant_frame_sp) {
+  m_stop_desc = std::move(stop_desc);
+}
+
+lldb::RecognizedStackFrameSP
+VerboseTrapFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
+  if (frame_sp->GetFrameIndex())
+    return {};
+
+  ThreadSP thread_sp = frame_sp->GetThread();
+  ProcessSP process_sp = thread_sp->GetProcess();
+
+  StackFrameSP most_relevant_frame_sp = thread_sp->GetStackFrameAtIndex(1);
+
+  if (!most_relevant_frame_sp) {
+    Log *log = GetLog(LLDBLog::Unwind);
+    LLDB_LOG(
+        log,
+        "Failed to find most relevant frame: Hit unwinding bound (1 frame)!");
+    return {};
+  }
+
+  SymbolContext sc = frame_sp->GetSymbolContext(eSymbolContextEverything);
+
+  if (!sc.block)
+    return {};
+
+  // The runtime error is set as the function name in the inlined function info
+  // of frame #0 by the compiler
+  const InlineFunctionInfo *inline_info = nullptr;
+  Block *inline_block = sc.block->GetContainingInlinedBlock();
+
+  if (!inline_block)
+    return {};
+
+  inline_info = sc.block->GetInlinedFunctionInfo();
+
+  if (!inline_info)
+    return {};
+
+  auto runtime_error = inline_info->GetName().GetString();
+
+  if (runtime_error.empty())
+    return {};
+
+  return lldb::RecognizedStackFrameSP(new VerboseTrapRecognizedStackFrame(
+      most_relevant_frame_sp, std::move(runtime_error)));
+}
+
+lldb::StackFrameSP VerboseTrapRecognizedStackFrame::GetMostRelevantFrame() {
+  return m_most_relevant_frame;
+}
+
+namespace lldb_private {
+
+void RegisterVerboseTrapFrameRecognizer(Process &process) {
+  RegularExpressionSP module_regex_sp = nullptr;
+  RegularExpressionSP symbol_regex_sp(
+      new RegularExpression("(__llvm_verbose_trap)"));
+
+  StackFrameRecognizerSP srf_recognizer_sp =
+      std::make_shared<VerboseTrapFrameRecognizer>();
+
+  process.GetTarget().GetFrameRecognizerManager().AddRecognizer(
+      srf_recognizer_sp, module_regex_sp, symbol_regex_sp, false);
+}
+
+} // namespace lldb_private
diff --git a/lldb/test/Shell/Recognizer/Inputs/verbose_trap.cpp 
b/lldb/test/Shell/Recognizer/Inputs/verbose_trap.cpp
new file mode 100644
index 00000000000000..6867c245e2fc9f
--- /dev/null
+++ b/lldb/test/Shell/Recognizer/Inputs/verbose_trap.cpp
@@ -0,0 +1,8 @@
+struct Dummy {
+  void func() { __builtin_verbose_trap("Function is not implemented"); }
+};
+
+int main() {
+  Dummy{}.func();
+  return 0;
+}
diff --git a/lldb/test/Shell/Recognizer/verbose_trap.test 
b/lldb/test/Shell/Recognizer/verbose_trap.test
new file mode 100644
index 00000000000000..7790354784afd7
--- /dev/null
+++ b/lldb/test/Shell/Recognizer/verbose_trap.test
@@ -0,0 +1,9 @@
+# RUN: %clang_host -g -O0 %S/Inputs/verbose_trap.cpp -o %t.out
+# RUN: %lldb -b -s %s %t.out | FileCheck %s
+run
+# CHECK: thread #{{.*}}stop reason = __llvm_verbose_trap: Function is not 
implemented
+frame info
+# CHECK: frame #{{.*}}`Dummy::func(this={{.*}}) at verbose_trap.cpp
+frame recognizer info 0
+# CHECK: frame 0 is recognized by Verbose Trap StackFrame Recognizer
+q

>From c7c5d269d811192c2554cf3615110e9da276507a Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Mon, 5 Feb 2024 18:32:27 +0000
Subject: [PATCH 2/6] fixup! simplify regex, replace error prefix with
 human-readable message

---
 lldb/source/Target/VerboseTrapFrameRecognizer.cpp | 15 ++++++++++-----
 lldb/test/Shell/Recognizer/verbose_trap.test      |  2 +-
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp 
b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
index d1a9ec18f8fe44..f15501f67734f7 100644
--- a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
+++ b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
@@ -8,6 +8,7 @@
 
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
+#include <filesystem>
 
 using namespace llvm;
 using namespace lldb;
@@ -55,13 +56,17 @@ 
VerboseTrapFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   if (!inline_info)
     return {};
 
-  auto runtime_error = inline_info->GetName().GetString();
-
-  if (runtime_error.empty())
+  auto error_message = inline_info->GetName().GetString();
+  if (error_message.empty())
     return {};
 
+  // Replaces "__llvm_verbose_trap :" with "Runtime Error: "
+  auto space_position = error_message.find(" ");
+  assert(space_position != std::string::npos);
+  error_message.replace(0, space_position, "Runtime Error:");
+
   return lldb::RecognizedStackFrameSP(new VerboseTrapRecognizedStackFrame(
-      most_relevant_frame_sp, std::move(runtime_error)));
+      most_relevant_frame_sp, std::move(error_message)));
 }
 
 lldb::StackFrameSP VerboseTrapRecognizedStackFrame::GetMostRelevantFrame() {
@@ -73,7 +78,7 @@ namespace lldb_private {
 void RegisterVerboseTrapFrameRecognizer(Process &process) {
   RegularExpressionSP module_regex_sp = nullptr;
   RegularExpressionSP symbol_regex_sp(
-      new RegularExpression("(__llvm_verbose_trap)"));
+      new RegularExpression("^__llvm_verbose_trap: "));
 
   StackFrameRecognizerSP srf_recognizer_sp =
       std::make_shared<VerboseTrapFrameRecognizer>();
diff --git a/lldb/test/Shell/Recognizer/verbose_trap.test 
b/lldb/test/Shell/Recognizer/verbose_trap.test
index 7790354784afd7..3fb3bd7abcd390 100644
--- a/lldb/test/Shell/Recognizer/verbose_trap.test
+++ b/lldb/test/Shell/Recognizer/verbose_trap.test
@@ -1,7 +1,7 @@
 # RUN: %clang_host -g -O0 %S/Inputs/verbose_trap.cpp -o %t.out
 # RUN: %lldb -b -s %s %t.out | FileCheck %s
 run
-# CHECK: thread #{{.*}}stop reason = __llvm_verbose_trap: Function is not 
implemented
+# CHECK: thread #{{.*}}stop reason = Runtime Error: Function is not implemented
 frame info
 # CHECK: frame #{{.*}}`Dummy::func(this={{.*}}) at verbose_trap.cpp
 frame recognizer info 0

>From 95912e3f8d302c61f9ece53036dcac1310303fba Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Mon, 5 Feb 2024 18:35:18 +0000
Subject: [PATCH 3/6] fixup! remove redundant header

---
 lldb/source/Target/VerboseTrapFrameRecognizer.cpp | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp 
b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
index f15501f67734f7..bd056803b489f1 100644
--- a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
+++ b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
@@ -8,7 +8,6 @@
 
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
-#include <filesystem>
 
 using namespace llvm;
 using namespace lldb;

>From df019ea63368b01745f2fc5a4bb7560235d9d873 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Mon, 5 Feb 2024 19:33:54 +0000
Subject: [PATCH 4/6] fixup! handle case where function name is in unexpected
 format

---
 lldb/source/Target/VerboseTrapFrameRecognizer.cpp | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp 
b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
index bd056803b489f1..7c5d633ac4e814 100644
--- a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
+++ b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
@@ -59,9 +59,18 @@ 
VerboseTrapFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
   if (error_message.empty())
     return {};
 
-  // Replaces "__llvm_verbose_trap :" with "Runtime Error: "
+  // Replaces "__llvm_verbose_trap: " with "Runtime Error: "
   auto space_position = error_message.find(" ");
-  assert(space_position != std::string::npos);
+  if (space_position == std::string::npos) {
+    Log *log = GetLog(LLDBLog::Unwind);
+    LLDB_LOGF(log,
+              "Unexpected function name format. Expected '<trap prefix>: "
+              "<trap message>' but got: '%s'.",
+              error_message.c_str());
+
+    return {};
+  }
+
   error_message.replace(0, space_position, "Runtime Error:");
 
   return lldb::RecognizedStackFrameSP(new VerboseTrapRecognizedStackFrame(

>From f7f6d26dddab6feca7f978f250be1f5e5f058eb4 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Tue, 12 Mar 2024 11:05:39 +0000
Subject: [PATCH 5/6] fixup! add license to header

---
 lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h 
b/lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h
index 7e045760a28be6..a17ba70b2f688a 100644
--- a/lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h
+++ b/lldb/include/lldb/Target/VerboseTrapFrameRecognizer.h
@@ -1,3 +1,11 @@
+//===-- VerboseTrapFrameRecognizer.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_TARGET_VERBOSETRAPFRAMERECOGNIZER_H
 #define LLDB_TARGET_VERBOSETRAPFRAMERECOGNIZER_H
 

>From 587ea970ff8f2f59a235b1ff3e41e5fccd3664a0 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuc...@gmail.com>
Date: Tue, 12 Mar 2024 11:07:24 +0000
Subject: [PATCH 6/6] fixup! hoist GetLog call; remove using-namespace
 declaration

---
 lldb/source/Target/VerboseTrapFrameRecognizer.cpp | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp 
b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
index 7c5d633ac4e814..bf16f5403e70d0 100644
--- a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
+++ b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
@@ -9,7 +9,6 @@
 #include "lldb/Utility/LLDBLog.h"
 #include "lldb/Utility/Log.h"
 
-using namespace llvm;
 using namespace lldb;
 using namespace lldb_private;
 
@@ -29,8 +28,8 @@ VerboseTrapFrameRecognizer::RecognizeFrame(lldb::StackFrameSP 
frame_sp) {
 
   StackFrameSP most_relevant_frame_sp = thread_sp->GetStackFrameAtIndex(1);
 
+  Log *log = GetLog(LLDBLog::Unwind);
   if (!most_relevant_frame_sp) {
-    Log *log = GetLog(LLDBLog::Unwind);
     LLDB_LOG(
         log,
         "Failed to find most relevant frame: Hit unwinding bound (1 frame)!");
@@ -62,7 +61,6 @@ VerboseTrapFrameRecognizer::RecognizeFrame(lldb::StackFrameSP 
frame_sp) {
   // Replaces "__llvm_verbose_trap: " with "Runtime Error: "
   auto space_position = error_message.find(" ");
   if (space_position == std::string::npos) {
-    Log *log = GetLog(LLDBLog::Unwind);
     LLDB_LOGF(log,
               "Unexpected function name format. Expected '<trap prefix>: "
               "<trap message>' but got: '%s'.",

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to