[Lldb-commits] [lldb] [lldb] Fix crash in frame recognizer list for a module-less recognizer (PR #224267)

Charles Zablit via lldb-commits lldb-commits at lists.llvm.org
Thu Sep 17 04:21:02 PDT 2026


https://github.com/charles-zablit created https://github.com/llvm/llvm-project/pull/224267

`StackFrameRecognizerManager::ForEach` hands `entry.module.GetCString()` to a callback whose module parameter is a `std::string`. However, `ConstString::GetCString` returns `nullptr` for a `ConstString()`, so a recognizer registered without a module name tries `strlen(nullptr)` and segfaults in `frame recognizer list` and in the recognizer-id completion handler, which share that callback.
    
This is why https://github.com/llvm/llvm-project/pull/197282 was reverted.
    
This patch passes `entry.module.GetStringRef().str()`, which is empty for both the null and the interned-empty ConstString. The regex branch is unchanged.

>From 8bbc09503184c092055cca3df87c1774d0a248da Mon Sep 17 00:00:00 2001
From: Charles Zablit <c_zablit at apple.com>
Date: Wed, 16 Sep 2026 18:00:25 +0100
Subject: [PATCH] [lldb] Fix crash in frame recognizer list for a module-less
 recognizer

---
 lldb/source/Target/StackFrameRecognizer.cpp   |  8 +++--
 .../Target/StackFrameRecognizerTest.cpp       | 29 +++++++++++++++++++
 2 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/lldb/source/Target/StackFrameRecognizer.cpp b/lldb/source/Target/StackFrameRecognizer.cpp
index 0542f942504ca..57b9e2b482b3e 100644
--- a/lldb/source/Target/StackFrameRecognizer.cpp
+++ b/lldb/source/Target/StackFrameRecognizer.cpp
@@ -150,9 +150,13 @@ void StackFrameRecognizerManager::ForEach(
                module_name, llvm::ArrayRef(ConstString(symbol_name)),
                entry.symbol_mangling, true);
     } else {
+      // A recognizer registered without a module matches any module. Use
+      // GetStringRef, since GetCString returns nullptr for an empty
+      // ConstString, which the std::string callback parameter can't be
+      // constructed from.
       callback(entry.recognizer_id, entry.enabled, entry.recognizer->GetName(),
-               entry.module.GetCString(), entry.symbols, entry.symbol_mangling,
-               false);
+               entry.module.GetStringRef().str(), entry.symbols,
+               entry.symbol_mangling, false);
     }
   }
 }
diff --git a/lldb/unittests/Target/StackFrameRecognizerTest.cpp b/lldb/unittests/Target/StackFrameRecognizerTest.cpp
index b356cd87d54ac..b15c3697055db 100644
--- a/lldb/unittests/Target/StackFrameRecognizerTest.cpp
+++ b/lldb/unittests/Target/StackFrameRecognizerTest.cpp
@@ -17,6 +17,7 @@
 #include "lldb/lldb-private.h"
 #include "llvm/Support/FormatVariadic.h"
 #include "gtest/gtest.h"
+#include <optional>
 
 using namespace lldb_private;
 using namespace lldb;
@@ -57,6 +58,15 @@ void RegisterDummyStackFrameRecognizer(StackFrameRecognizerManager &manager) {
                         Mangled::NamePreference::ePreferDemangled, false);
 }
 
+void RegisterModulelessStackFrameRecognizer(
+    StackFrameRecognizerManager &manager) {
+  StackFrameRecognizerSP dummy_recognizer_sp(new DummyStackFrameRecognizer());
+
+  manager.AddRecognizer(dummy_recognizer_sp, ConstString(),
+                        {ConstString("boom")},
+                        Mangled::NamePreference::ePreferDemangled, false);
+}
+
 } // namespace
 
 TEST_F(StackFrameRecognizerTest, NullModuleRegex) {
@@ -76,3 +86,22 @@ TEST_F(StackFrameRecognizerTest, NullModuleRegex) {
 
   EXPECT_TRUE(any_printed);
 }
+
+TEST_F(StackFrameRecognizerTest, EmptyModuleName) {
+  DebuggerSP debugger_sp = Debugger::CreateInstance();
+  ASSERT_TRUE(debugger_sp);
+
+  StackFrameRecognizerManager manager;
+
+  RegisterModulelessStackFrameRecognizer(manager);
+
+  std::optional<std::string> printed_module;
+  manager.ForEach([&printed_module](uint32_t recognizer_id, bool enabled,
+                                    std::string name, std::string module,
+                                    llvm::ArrayRef<ConstString> symbols,
+                                    Mangled::NamePreference symbol_mangling,
+                                    bool regexp) { printed_module = module; });
+
+  ASSERT_TRUE(printed_module);
+  EXPECT_TRUE(printed_module->empty());
+}



More information about the lldb-commits mailing list