[Lldb-commits] [lldb] [lldb] Add frame recognizer for __builtin_verbose_trap (PR #80368)
Michael Buch via lldb-commits
lldb-commits at lists.llvm.org
Fri Jul 12 16:13:17 PDT 2024
https://github.com/Michael137 updated https://github.com/llvm/llvm-project/pull/80368
>From d7c77e6ae69449985300c3909e835e35be3ba3e9 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Thu, 25 Jan 2024 11:05:02 +0000
Subject: [PATCH 1/5] [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 000000000000..7e045760a28b
--- /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 cf4818eae3eb..8186ccbea27d 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 dc7f6c9e86a4..e72982db987a 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/AddressableBits.h"
#include "lldb/Utility/Event.h"
#include "lldb/Utility/LLDBLog.h"
@@ -525,6 +526,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 000000000000..d1a9ec18f8fe
--- /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 000000000000..6867c245e2fc
--- /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 000000000000..7790354784af
--- /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 02d69d9142086fed2f4835cc11d39e94642c0f1d Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 5 Feb 2024 18:32:27 +0000
Subject: [PATCH 2/5] 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 d1a9ec18f8fe..f15501f67734 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 7790354784af..3fb3bd7abcd3 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 c09c6e6138e48e14fbb6f7ba34db019ebd0ca178 Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 5 Feb 2024 18:35:18 +0000
Subject: [PATCH 3/5] 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 f15501f67734..bd056803b489 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 5bb51959183c797b050d6154e2232a3fa5611abd Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Mon, 5 Feb 2024 19:33:54 +0000
Subject: [PATCH 4/5] 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 bd056803b489..7c5d633ac4e8 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 4dd2c33b8443fa4704d9a3e30e5e2d73337887af Mon Sep 17 00:00:00 2001
From: Michael Buch <michaelbuch12 at gmail.com>
Date: Fri, 12 Jul 2024 18:38:14 +0100
Subject: [PATCH 5/5] fixup! adjust to new __builtin_verbose_trap message
format
---
.../Target/VerboseTrapFrameRecognizer.cpp | 54 +++++++++++++------
.../Shell/Recognizer/Inputs/verbose_trap.cpp | 6 ++-
lldb/test/Shell/Recognizer/verbose_trap.test | 19 +++++--
3 files changed, 60 insertions(+), 19 deletions(-)
diff --git a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
index 7c5d633ac4e8..26bfb2e7363c 100644
--- a/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
+++ b/lldb/source/Target/VerboseTrapFrameRecognizer.cpp
@@ -4,11 +4,14 @@
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/Process.h"
+#include "lldb/Target/StackFrameRecognizer.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
+#include "clang/CodeGen/ModuleBuilder.h"
+
using namespace llvm;
using namespace lldb;
using namespace lldb_private;
@@ -55,26 +58,47 @@ VerboseTrapFrameRecognizer::RecognizeFrame(lldb::StackFrameSP frame_sp) {
if (!inline_info)
return {};
- auto error_message = inline_info->GetName().GetString();
- if (error_message.empty())
+ auto func_name = inline_info->GetName().GetStringRef();
+ if (func_name.empty())
return {};
- // 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'.",
- error_message.c_str());
+ static auto trap_regex =
+ llvm::Regex(llvm::formatv("^{0}\\$(.*)\\$(.*)$", ClangTrapPrefix).str());
+ SmallVector<llvm::StringRef, 2> matches;
+ std::string regex_err_msg;
+ if (!trap_regex.match(func_name, &matches, ®ex_err_msg)) {
+ LLDB_LOGF(GetLog(LLDBLog::Unwind),
+ "Failed to parse match trap regex for '%s': %s", func_name.data(),
+ regex_err_msg.c_str());
+
+ return {};
+ }
+
+ // For `__clang_trap_msg$category$message$` we expect 3 matches:
+ // 1. entire string
+ // 2. category
+ // 3. message
+ if (matches.size() != 3) {
+ LLDB_LOGF(GetLog(LLDBLog::Unwind),
+ "Unexpected function name format. Expected '<trap prefix>$<trap "
+ "category>$<trap message>'$ but got: '%s'. %zu",
+ func_name.data(), matches.size());
return {};
}
- error_message.replace(0, space_position, "Runtime Error:");
+ auto category = matches[1];
+ auto message = matches[2];
+
+ std::string stop_reason =
+ category.empty() ? "<empty category>" : category.str();
+ if (!message.empty()) {
+ stop_reason += ": ";
+ stop_reason += message.str();
+ }
- return lldb::RecognizedStackFrameSP(new VerboseTrapRecognizedStackFrame(
- most_relevant_frame_sp, std::move(error_message)));
+ return std::make_shared<VerboseTrapRecognizedStackFrame>(
+ most_relevant_frame_sp, std::move(stop_reason));
}
lldb::StackFrameSP VerboseTrapRecognizedStackFrame::GetMostRelevantFrame() {
@@ -85,8 +109,8 @@ namespace lldb_private {
void RegisterVerboseTrapFrameRecognizer(Process &process) {
RegularExpressionSP module_regex_sp = nullptr;
- RegularExpressionSP symbol_regex_sp(
- new RegularExpression("^__llvm_verbose_trap: "));
+ auto symbol_regex_sp = std::make_shared<RegularExpression>(
+ llvm::formatv("^{0}", ClangTrapPrefix).str());
StackFrameRecognizerSP srf_recognizer_sp =
std::make_shared<VerboseTrapFrameRecognizer>();
diff --git a/lldb/test/Shell/Recognizer/Inputs/verbose_trap.cpp b/lldb/test/Shell/Recognizer/Inputs/verbose_trap.cpp
index 6867c245e2fc..89962b543799 100644
--- a/lldb/test/Shell/Recognizer/Inputs/verbose_trap.cpp
+++ b/lldb/test/Shell/Recognizer/Inputs/verbose_trap.cpp
@@ -1,5 +1,9 @@
+#if !defined(VERBOSE_TRAP_TEST_CATEGORY) || !defined(VERBOSE_TRAP_TEST_MESSAGE)
+#error Please define required macros
+#endif
+
struct Dummy {
- void func() { __builtin_verbose_trap("Function is not implemented"); }
+ void func() { __builtin_verbose_trap(VERBOSE_TRAP_TEST_CATEGORY, VERBOSE_TRAP_TEST_MESSAGE); }
};
int main() {
diff --git a/lldb/test/Shell/Recognizer/verbose_trap.test b/lldb/test/Shell/Recognizer/verbose_trap.test
index 3fb3bd7abcd3..45ef84bef611 100644
--- a/lldb/test/Shell/Recognizer/verbose_trap.test
+++ b/lldb/test/Shell/Recognizer/verbose_trap.test
@@ -1,7 +1,20 @@
-# RUN: %clang_host -g -O0 %S/Inputs/verbose_trap.cpp -o %t.out
-# RUN: %lldb -b -s %s %t.out | FileCheck %s
+# RUN: %clang_host -g -O0 %S/Inputs/verbose_trap.cpp -o %t.out -DVERBOSE_TRAP_TEST_CATEGORY=\"Foo\" -DVERBOSE_TRAP_TEST_MESSAGE=\"Bar\"
+# RUN: %lldb -b -s %s %t.out | FileCheck %s --check-prefixes=CHECK,CHECK-BOTH
+#
+# RUN: %clang_host -g -O0 %S/Inputs/verbose_trap.cpp -o %t.out -DVERBOSE_TRAP_TEST_CATEGORY=\"\" -DVERBOSE_TRAP_TEST_MESSAGE=\"Bar\"
+# RUN: %lldb -b -s %s %t.out | FileCheck %s --check-prefixes=CHECK,CHECK-MESSAGE_ONLY
+#
+# RUN: %clang_host -g -O0 %S/Inputs/verbose_trap.cpp -o %t.out -DVERBOSE_TRAP_TEST_CATEGORY=\"Foo\" -DVERBOSE_TRAP_TEST_MESSAGE=\"\"
+# RUN: %lldb -b -s %s %t.out | FileCheck %s --check-prefixes=CHECK,CHECK-CATEGORY_ONLY
+#
+# RUN: %clang_host -g -O0 %S/Inputs/verbose_trap.cpp -o %t.out -DVERBOSE_TRAP_TEST_CATEGORY=\"\" -DVERBOSE_TRAP_TEST_MESSAGE=\"\"
+# RUN: %lldb -b -s %s %t.out | FileCheck %s --check-prefixes=CHECK,CHECK-NONE
+
run
-# CHECK: thread #{{.*}}stop reason = Runtime Error: Function is not implemented
+# CHECK-BOTH: thread #{{.*}}stop reason = Foo: Bar
+# CHECK-MESSAGE_ONLY: thread #{{.*}}stop reason = <empty category>: Bar
+# CHECK-CATEGORY_ONLY: thread #{{.*}}stop reason = Foo
+# CHECK-NONE: thread #{{.*}}stop reason = <empty category>
frame info
# CHECK: frame #{{.*}}`Dummy::func(this={{.*}}) at verbose_trap.cpp
frame recognizer info 0
More information about the lldb-commits
mailing list