Skip to content

Commit 7b3455e

Browse files
authored
[lldb] Fix double free in CommandPluginInterfaceImplementation (#131658)
The class was taking ownership of the SBCommandPluginInterface pointer it was passed in, by wrapping it in a shared pointer. This causes a double free in the unit test when the object is destroyed and the same pointer gets freed once when the SBCommandPluginInterface goes away and then again when the shared pointer hits a zero refcount.
1 parent 93df3e8 commit 7b3455e

File tree

2 files changed

+12
-8
lines changed

2 files changed

+12
-8
lines changed

lldb/source/API/SBCommandInterpreter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class CommandPluginInterfaceImplementation : public CommandObjectParsed {
7777
SBDebugger debugger_sb(m_interpreter.GetDebugger().shared_from_this());
7878
m_backend->DoExecute(debugger_sb, command.GetArgumentVector(), sb_return);
7979
}
80-
std::shared_ptr<lldb::SBCommandPluginInterface> m_backend;
80+
lldb::SBCommandPluginInterface *m_backend;
8181
std::optional<std::string> m_auto_repeat_command;
8282
};
8383
} // namespace lldb_private

lldb/unittests/API/SBCommandInterpreterTest.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,28 @@
66
//
77
//===----------------------------------------------------------------------===/
88

9-
#include "gtest/gtest.h"
10-
119
// Use the umbrella header for -Wdocumentation.
1210
#include "lldb/API/LLDB.h"
1311

12+
#include "TestingSupport/SubsystemRAII.h"
13+
#include "lldb/API/SBDebugger.h"
14+
#include "gtest/gtest.h"
1415
#include <cstring>
1516
#include <string>
1617

1718
using namespace lldb;
19+
using namespace lldb_private;
1820

1921
class SBCommandInterpreterTest : public testing::Test {
2022
protected:
2123
void SetUp() override {
22-
SBDebugger::Initialize();
23-
m_dbg = SBDebugger::Create(/*source_init_files=*/false);
24+
debugger = SBDebugger::Create(/*source_init_files=*/false);
2425
}
2526

26-
SBDebugger m_dbg;
27+
void TearDown() override { SBDebugger::Destroy(debugger); }
28+
29+
SubsystemRAII<lldb::SBDebugger> subsystems;
30+
SBDebugger debugger;
2731
};
2832

2933
class DummyCommand : public SBCommandPluginInterface {
@@ -44,7 +48,7 @@ class DummyCommand : public SBCommandPluginInterface {
4448
TEST_F(SBCommandInterpreterTest, SingleWordCommand) {
4549
// We first test a command without autorepeat
4650
DummyCommand dummy("It worked");
47-
SBCommandInterpreter interp = m_dbg.GetCommandInterpreter();
51+
SBCommandInterpreter interp = debugger.GetCommandInterpreter();
4852
interp.AddCommand("dummy", &dummy, /*help=*/nullptr);
4953
{
5054
SBCommandReturnObject result;
@@ -78,7 +82,7 @@ TEST_F(SBCommandInterpreterTest, SingleWordCommand) {
7882
}
7983

8084
TEST_F(SBCommandInterpreterTest, MultiWordCommand) {
81-
SBCommandInterpreter interp = m_dbg.GetCommandInterpreter();
85+
SBCommandInterpreter interp = debugger.GetCommandInterpreter();
8286
auto command = interp.AddMultiwordCommand("multicommand", /*help=*/nullptr);
8387
// We first test a subcommand without autorepeat
8488
DummyCommand subcommand("It worked again");

0 commit comments

Comments
 (0)