Skip to content

Commit 212caa6

Browse files
committed
[lldb/Target] Fix frame recognizer list crash when registered with nullptr
One way to register a recognizer is to use RegularExpressionSP for the module and symbol. In order to match a symbol regardless of the module, the recognizer can be registered with a nullptr for the module. However, this cause the frame recognizer list command to crash because it calls RegularExpression::GetText without checking if the shared pointer is valid. This patch adds checks for the symbol and module RegularExpressionSP. Differential Revision: https://reviews.llvm.org/D74212 Signed-off-by: Med Ismail Bennani <[email protected]>
1 parent 377d5d2 commit 212caa6

File tree

3 files changed

+96
-2
lines changed

3 files changed

+96
-2
lines changed

lldb/source/Target/StackFrameRecognizer.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,17 @@ class StackFrameRecognizerManagerImpl {
7070
std::string symbol, bool regexp)> const &callback) {
7171
for (auto entry : m_recognizers) {
7272
if (entry.is_regexp) {
73-
callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module_regexp->GetText(),
74-
entry.symbol_regexp->GetText(), true);
73+
std::string module_name;
74+
std::string symbol_name;
75+
76+
if (entry.module_regexp)
77+
module_name = entry.module_regexp->GetText().str();
78+
if (entry.symbol_regexp)
79+
symbol_name = entry.symbol_regexp->GetText().str();
80+
81+
callback(entry.recognizer_id, entry.recognizer->GetName(), module_name,
82+
symbol_name, true);
83+
7584
} else {
7685
callback(entry.recognizer_id, entry.recognizer->GetName(), entry.module.GetCString(),
7786
entry.symbol.GetCString(), false);

lldb/unittests/Target/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ add_lldb_unittest(TargetTests
33
MemoryRegionInfoTest.cpp
44
ModuleCacheTest.cpp
55
PathMappingListTest.cpp
6+
StackFrameRecognizerTest.cpp
67

78
LINK_LIBS
89
lldbCore
910
lldbHost
1011
lldbPluginObjectFileELF
1112
lldbPluginPlatformLinux
1213
lldbPluginSymbolFileSymtab
14+
lldbTarget
1315
lldbSymbol
1416
lldbUtility
1517
lldbUtilityHelpers
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
//===-- StackFrameRecognizerTest.cpp --------------------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "lldb/Target/StackFrameRecognizer.h"
10+
#include "Plugins/Platform/Linux/PlatformLinux.h"
11+
#include "lldb/Core/Debugger.h"
12+
#include "lldb/Host/FileSystem.h"
13+
#include "lldb/Host/HostInfo.h"
14+
#include "lldb/Utility/Reproducer.h"
15+
#include "lldb/lldb-enumerations.h"
16+
#include "lldb/lldb-forward.h"
17+
#include "lldb/lldb-private-enumerations.h"
18+
#include "lldb/lldb-private.h"
19+
#include "llvm/Support/FormatVariadic.h"
20+
#include "gtest/gtest.h"
21+
22+
using namespace lldb_private;
23+
using namespace lldb_private::repro;
24+
using namespace lldb;
25+
26+
namespace {
27+
class StackFrameRecognizerTest : public ::testing::Test {
28+
public:
29+
void SetUp() override {
30+
llvm::cantFail(Reproducer::Initialize(ReproducerMode::Off, llvm::None));
31+
FileSystem::Initialize();
32+
HostInfo::Initialize();
33+
34+
// Pretend Linux is the host platform.
35+
platform_linux::PlatformLinux::Initialize();
36+
ArchSpec arch("powerpc64-pc-linux");
37+
Platform::SetHostPlatform(
38+
platform_linux::PlatformLinux::CreateInstance(true, &arch));
39+
}
40+
41+
void TearDown() override {
42+
platform_linux::PlatformLinux::Terminate();
43+
HostInfo::Terminate();
44+
FileSystem::Terminate();
45+
Reproducer::Terminate();
46+
}
47+
};
48+
49+
class DummyStackFrameRecognizer : public StackFrameRecognizer {
50+
public:
51+
std::string GetName() override { return "Dummy StackFrame Recognizer"; }
52+
};
53+
54+
void RegisterDummyStackFrameRecognizer() {
55+
static llvm::once_flag g_once_flag;
56+
57+
llvm::call_once(g_once_flag, []() {
58+
RegularExpressionSP module_regex_sp = nullptr;
59+
RegularExpressionSP symbol_regex_sp(new RegularExpression("boom"));
60+
61+
StackFrameRecognizerSP dummy_recognizer_sp(new DummyStackFrameRecognizer());
62+
63+
StackFrameRecognizerManager::AddRecognizer(
64+
dummy_recognizer_sp, module_regex_sp, symbol_regex_sp, false);
65+
});
66+
}
67+
68+
} // namespace
69+
70+
TEST_F(StackFrameRecognizerTest, NullModuleRegex) {
71+
DebuggerSP debugger_sp = Debugger::CreateInstance();
72+
ASSERT_TRUE(debugger_sp);
73+
74+
RegisterDummyStackFrameRecognizer();
75+
76+
bool any_printed = false;
77+
StackFrameRecognizerManager::ForEach(
78+
[&any_printed](uint32_t recognizer_id, std::string name,
79+
std::string function, std::string symbol,
80+
bool regexp) { any_printed = true; });
81+
82+
EXPECT_TRUE(any_printed);
83+
}

0 commit comments

Comments
 (0)