Skip to content

Commit f534c55

Browse files
committed
Remove StoreTarget/TakeTarget
1 parent d1cc643 commit f534c55

File tree

8 files changed

+40
-190
lines changed

8 files changed

+40
-190
lines changed

lldb/tools/lldb-dap/DAP.cpp

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1309,18 +1309,34 @@ void DAP::StartEventThreads() {
13091309
StartEventThread();
13101310
}
13111311

1312-
llvm::Error DAP::InitializeDebugger(std::optional<lldb::user_id_t> target_id) {
1312+
llvm::Error DAP::InitializeDebugger(std::optional<int> debugger_id,
1313+
std::optional<lldb::user_id_t> target_id) {
1314+
// Validate that both debugger_id and target_id are provided together.
1315+
if (debugger_id.has_value() != target_id.has_value()) {
1316+
return llvm::createStringError(
1317+
"Both debuggerId and targetId must be specified together for debugger "
1318+
"reuse, or both must be omitted to create a new debugger");
1319+
}
1320+
13131321
// Initialize debugger instance (shared or individual).
1314-
if (target_id) {
1315-
std::optional<lldb::SBTarget> shared_target =
1316-
DAPSessionManager::GetInstance().TakeTargetById(*target_id);
1317-
// If the target ID is not valid, then we won't find a target.
1318-
if (!shared_target) {
1322+
if (debugger_id && target_id) {
1323+
// Find the existing debugger by ID
1324+
debugger = lldb::SBDebugger::FindDebuggerWithID(*debugger_id);
1325+
if (!debugger.IsValid()) {
1326+
return llvm::createStringError(
1327+
"Unable to find existing debugger for debugger ID");
1328+
}
1329+
1330+
// Find the target within the debugger by its globally unique ID
1331+
lldb::SBTarget shared_target =
1332+
debugger.FindTargetByGloballyUniqueID(*target_id);
1333+
if (!shared_target.IsValid()) {
13191334
return llvm::createStringError(
13201335
"Unable to find existing target for target ID");
13211336
}
1322-
// Get the debugger from the target and set it up.
1323-
debugger = shared_target->GetDebugger();
1337+
1338+
// Set the target for this DAP session.
1339+
SetTarget(shared_target);
13241340
StartEventThreads();
13251341
return llvm::Error::success();
13261342
}
@@ -1568,18 +1584,18 @@ void DAP::EventThread() {
15681584
} else if (event_mask & lldb::SBTarget::eBroadcastBitNewTargetCreated) {
15691585
auto target = lldb::SBTarget::GetTargetFromEvent(event);
15701586

1571-
// Generate unique target ID and store the target for handoff.
15721587
lldb::user_id_t target_id = target.GetGloballyUniqueID();
1573-
DAPSessionManager::GetInstance().StoreTargetById(target_id, target);
1588+
lldb::SBDebugger target_debugger = target.GetDebugger();
1589+
int debugger_id = target_debugger.GetID();
15741590

1575-
// We create an attach config that will select the unique
1576-
// target ID of the created target. The DAP instance will attach to
1577-
// this existing target and the debug session will be ready to go.
1591+
// We create an attach config that contains the debugger ID and target
1592+
// ID. The new DAP instance will use these IDs to find the existing
1593+
// debugger and target via FindDebuggerWithID and
1594+
// FindTargetByGloballyUniqueID.
15781595
llvm::json::Object attach_config;
15791596

1580-
// If we have a process name, add command to attach to the same
1581-
// process name.
15821597
attach_config.try_emplace("type", "lldb");
1598+
attach_config.try_emplace("debuggerId", debugger_id);
15831599
attach_config.try_emplace("targetId", target_id);
15841600
const char *session_name = target.GetTargetSessionName();
15851601
attach_config.try_emplace("name", session_name);

lldb/tools/lldb-dap/DAP.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,8 @@ struct DAP final : public DAPTransport::MessageHandler {
431431

432432
/// Perform complete DAP initialization in one call.
433433
llvm::Error
434-
InitializeDebugger(std::optional<lldb::user_id_t> target_idx = std::nullopt);
434+
InitializeDebugger(std::optional<int> debugger_id = std::nullopt,
435+
std::optional<lldb::user_id_t> target_id = std::nullopt);
435436

436437
/// Start event handling threads based on client capabilities.
437438
void StartEventThreads();

lldb/tools/lldb-dap/DAPSessionManager.cpp

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,6 @@ void DAPSessionManager::RegisterSession(lldb_private::MainLoop *loop,
5050
void DAPSessionManager::UnregisterSession(lldb_private::MainLoop *loop) {
5151
std::unique_lock<std::mutex> lock(m_sessions_mutex);
5252
m_active_sessions.erase(loop);
53-
54-
// Clean up shared resources when the last session exits.
55-
if (m_active_sessions.empty())
56-
CleanupSharedResources();
57-
5853
std::notify_all_at_thread_exit(m_sessions_condition, std::move(lock));
5954
}
6055

@@ -118,23 +113,6 @@ DAPSessionManager::GetEventThreadForDebugger(lldb::SBDebugger debugger,
118113
return new_thread_sp;
119114
}
120115

121-
void DAPSessionManager::StoreTargetById(lldb::user_id_t target_id,
122-
lldb::SBTarget target) {
123-
std::lock_guard<std::mutex> lock(m_sessions_mutex);
124-
m_target_map[target_id] = target;
125-
}
126-
127-
std::optional<lldb::SBTarget>
128-
DAPSessionManager::TakeTargetById(lldb::user_id_t target_id) {
129-
std::lock_guard<std::mutex> lock(m_sessions_mutex);
130-
auto pos = m_target_map.find(target_id);
131-
if (pos == m_target_map.end())
132-
return std::nullopt;
133-
lldb::SBTarget target = pos->second;
134-
m_target_map.erase(pos);
135-
return target;
136-
}
137-
138116
DAP *DAPSessionManager::FindDAPForTarget(lldb::SBTarget target) {
139117
std::lock_guard<std::mutex> lock(m_sessions_mutex);
140118

@@ -145,13 +123,6 @@ DAP *DAPSessionManager::FindDAPForTarget(lldb::SBTarget target) {
145123
return nullptr;
146124
}
147125

148-
void DAPSessionManager::CleanupSharedResources() {
149-
// Note: Caller must hold m_sessions_mutex.
150-
// SBTarget destructors will handle cleanup when the map entries are
151-
// destroyed.
152-
m_target_map.clear();
153-
}
154-
155126
void DAPSessionManager::ReleaseExpiredEventThreads() {
156127
std::lock_guard<std::mutex> lock(m_sessions_mutex);
157128
for (auto it = m_debugger_event_threads.begin();

lldb/tools/lldb-dap/DAPSessionManager.h

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -71,31 +71,6 @@ class DAPSessionManager {
7171
/// DisconnectAllSessions() was called and any disconnection failed.
7272
llvm::Error WaitForAllSessionsToDisconnect();
7373

74-
/// Store a target for later retrieval by another session.
75-
///
76-
/// When a new target is dynamically created (e.g., via scripting hooks or
77-
/// child process debugging), it needs to be handed off to a new DAP session.
78-
/// This method stores the target in a temporary map using its globally unique
79-
/// ID so that the new session can retrieve it via TakeTargetById().
80-
///
81-
/// \param target_id The globally unique ID of the target (from
82-
/// SBTarget::GetGloballyUniqueID()).
83-
/// \param target The target to store.
84-
void StoreTargetById(lldb::user_id_t target_id, lldb::SBTarget target);
85-
86-
/// Retrieve and remove a stored target by its globally unique target ID.
87-
///
88-
/// This method is called during the attach request when a new DAP session
89-
/// wants to attach to a dynamically created target. The target is removed
90-
/// from the map after retrieval because:
91-
/// 1. Each target should only be attached to by one DAP session
92-
/// 2. Once attached, the DAP session takes ownership of the target
93-
/// 3. Keeping the target in the map would prevent proper cleanup
94-
///
95-
/// \param target_id The globally unique ID of the target to retrieve.
96-
/// \return The target if found, std::nullopt otherwise.
97-
std::optional<lldb::SBTarget> TakeTargetById(lldb::user_id_t target_id);
98-
9974
/// Get or create event thread for a specific debugger.
10075
std::shared_ptr<ManagedEventThread>
10176
GetEventThreadForDebugger(lldb::SBDebugger debugger, DAP *requesting_dap);
@@ -108,9 +83,6 @@ class DAPSessionManager {
10883
return GetInstance().FindDAPForTarget(target);
10984
}
11085

111-
/// Clean up shared resources when the last session exits.
112-
void CleanupSharedResources();
113-
11486
/// Clean up expired event threads from the collection.
11587
void ReleaseExpiredEventThreads();
11688

@@ -129,10 +101,6 @@ class DAPSessionManager {
129101
std::condition_variable m_sessions_condition;
130102
std::map<lldb_private::MainLoop *, DAP *> m_active_sessions;
131103

132-
/// Map from target ID to target for handing off newly created targets
133-
/// between sessions.
134-
std::map<lldb::user_id_t, lldb::SBTarget> m_target_map;
135-
136104
/// Map from debugger ID to its event thread, used when multiple DAP sessions
137105
/// share the same debugger instance.
138106
std::map<lldb::user_id_t, std::weak_ptr<ManagedEventThread>>

lldb/tools/lldb-dap/Handler/AttachRequestHandler.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ namespace lldb_dap {
3232
Error AttachRequestHandler::Run(const AttachRequestArguments &args) const {
3333
// Initialize DAP debugger and related components if not sharing previously
3434
// launched debugger.
35+
std::optional<int> debugger_id = args.debuggerId;
3536
std::optional<lldb::user_id_t> target_id = args.targetId;
36-
if (Error err = dap.InitializeDebugger(target_id))
37+
if (Error err = dap.InitializeDebugger(debugger_id, target_id))
3738
return err;
3839

3940
// Validate that we have a well formed attach request.

lldb/tools/lldb-dap/Protocol/ProtocolRequests.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,8 @@ bool fromJSON(const json::Value &Params, AttachRequestArguments &ARA,
317317
O.mapOptional("gdb-remote-port", ARA.gdbRemotePort) &&
318318
O.mapOptional("gdb-remote-hostname", ARA.gdbRemoteHostname) &&
319319
O.mapOptional("coreFile", ARA.coreFile) &&
320-
O.mapOptional("targetId", ARA.targetId);
320+
O.mapOptional("targetId", ARA.targetId) &&
321+
O.mapOptional("debuggerId", ARA.debuggerId);
321322
}
322323

323324
bool fromJSON(const json::Value &Params, ContinueArguments &CA, json::Path P) {

lldb/tools/lldb-dap/Protocol/ProtocolRequests.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,9 @@ struct AttachRequestArguments {
352352
/// Unique ID of an existing target to attach to.
353353
std::optional<lldb::user_id_t> targetId;
354354

355+
/// ID of an existing debugger instance to use.
356+
std::optional<int> debuggerId;
357+
355358
/// @}
356359
};
357360
bool fromJSON(const llvm::json::Value &, AttachRequestArguments &,

lldb/unittests/DAP/DAPSessionManagerTest.cpp

Lines changed: 0 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -25,117 +25,6 @@ TEST_F(DAPSessionManagerTest, GetInstanceReturnsSameSingleton) {
2525
EXPECT_EQ(&instance1, &instance2);
2626
}
2727

28-
TEST_F(DAPSessionManagerTest, StoreAndTakeTarget) {
29-
DAPSessionManager &manager = DAPSessionManager::GetInstance();
30-
31-
SBDebugger debugger = SBDebugger::Create();
32-
ASSERT_TRUE(debugger.IsValid());
33-
// Create an empty target (no executable) since we're only testing session
34-
// management functionality, not actual debugging operations.
35-
SBTarget target = debugger.CreateTarget("");
36-
ASSERT_TRUE(target.IsValid());
37-
38-
uint32_t target_id = target.GetGloballyUniqueID();
39-
manager.StoreTargetById(target_id, target);
40-
41-
// Retrieval consumes the target (removes from map).
42-
std::optional<SBTarget> retrieved = manager.TakeTargetById(target_id);
43-
ASSERT_TRUE(retrieved.has_value());
44-
EXPECT_TRUE(retrieved->IsValid());
45-
// Verify we got the correct target back.
46-
EXPECT_EQ(retrieved->GetDebugger().GetID(), debugger.GetID());
47-
EXPECT_EQ(*retrieved, target);
48-
49-
// Second retrieval should fail (one-time retrieval semantics).
50-
std::optional<SBTarget> second_retrieval = manager.TakeTargetById(target_id);
51-
EXPECT_FALSE(second_retrieval.has_value());
52-
53-
SBDebugger::Destroy(debugger);
54-
}
55-
56-
TEST_F(DAPSessionManagerTest, GetTargetWithInvalidId) {
57-
DAPSessionManager &manager = DAPSessionManager::GetInstance();
58-
59-
std::optional<SBTarget> result = manager.TakeTargetById(99999);
60-
61-
EXPECT_FALSE(result.has_value());
62-
}
63-
64-
TEST_F(DAPSessionManagerTest, MultipleTargetsWithDifferentIds) {
65-
DAPSessionManager &manager = DAPSessionManager::GetInstance();
66-
67-
SBDebugger debugger1 = SBDebugger::Create();
68-
SBDebugger debugger2 = SBDebugger::Create();
69-
ASSERT_TRUE(debugger1.IsValid());
70-
ASSERT_TRUE(debugger2.IsValid());
71-
// Create empty targets (no executable) since we're only testing session
72-
// management functionality, not actual debugging operations.
73-
SBTarget target1 = debugger1.CreateTarget("");
74-
SBTarget target2 = debugger2.CreateTarget("");
75-
ASSERT_TRUE(target1.IsValid());
76-
ASSERT_TRUE(target2.IsValid());
77-
78-
uint32_t target_id_1 = target1.GetGloballyUniqueID();
79-
uint32_t target_id_2 = target2.GetGloballyUniqueID();
80-
81-
// Sanity check the targets have distinct IDs.
82-
EXPECT_NE(target_id_1, target_id_2);
83-
84-
manager.StoreTargetById(target_id_1, target1);
85-
manager.StoreTargetById(target_id_2, target2);
86-
87-
std::optional<SBTarget> retrieved1 = manager.TakeTargetById(target_id_1);
88-
ASSERT_TRUE(retrieved1.has_value());
89-
EXPECT_TRUE(retrieved1->IsValid());
90-
// Verify we got the correct target by comparing debugger and target IDs.
91-
EXPECT_EQ(retrieved1->GetDebugger().GetID(), debugger1.GetID());
92-
EXPECT_EQ(*retrieved1, target1);
93-
94-
std::optional<SBTarget> retrieved2 = manager.TakeTargetById(target_id_2);
95-
ASSERT_TRUE(retrieved2.has_value());
96-
EXPECT_TRUE(retrieved2->IsValid());
97-
EXPECT_EQ(retrieved2->GetDebugger().GetID(), debugger2.GetID());
98-
EXPECT_EQ(*retrieved2, target2);
99-
100-
SBDebugger::Destroy(debugger1);
101-
SBDebugger::Destroy(debugger2);
102-
}
103-
104-
TEST_F(DAPSessionManagerTest, CleanupSharedResources) {
105-
DAPSessionManager &manager = DAPSessionManager::GetInstance();
106-
107-
SBDebugger debugger = SBDebugger::Create();
108-
ASSERT_TRUE(debugger.IsValid());
109-
// Create empty targets (no executable) since we're only testing session
110-
// management functionality, not actual debugging operations.
111-
SBTarget target1 = debugger.CreateTarget("");
112-
SBTarget target2 = debugger.CreateTarget("");
113-
ASSERT_TRUE(target1.IsValid());
114-
ASSERT_TRUE(target2.IsValid());
115-
116-
uint32_t target_id_1 = target1.GetGloballyUniqueID();
117-
uint32_t target_id_2 = target2.GetGloballyUniqueID();
118-
119-
// Sanity check the targets have distinct IDs.
120-
EXPECT_NE(target_id_1, target_id_2);
121-
122-
// Store multiple targets to verify cleanup removes them all.
123-
manager.StoreTargetById(target_id_1, target1);
124-
manager.StoreTargetById(target_id_2, target2);
125-
126-
// Cleanup should remove all stored targets.
127-
manager.CleanupSharedResources();
128-
129-
// Verify both targets are gone after cleanup.
130-
std::optional<SBTarget> result1 = manager.TakeTargetById(target_id_1);
131-
EXPECT_FALSE(result1.has_value());
132-
133-
std::optional<SBTarget> result2 = manager.TakeTargetById(target_id_2);
134-
EXPECT_FALSE(result2.has_value());
135-
136-
SBDebugger::Destroy(debugger);
137-
}
138-
13928
// UnregisterSession uses std::notify_all_at_thread_exit, so it must be called
14029
// from a separate thread to properly release the mutex on thread exit.
14130
TEST_F(DAPSessionManagerTest, RegisterAndUnregisterSession) {

0 commit comments

Comments
 (0)