Skip to content

Commit 322315b

Browse files
committed
[lldb] Correctly detach (rather than kill) when connecting with gdb-remote
We weren't setting `m_should_detach` when going through the `DoConnectRemote` code path. This meant that when you would attaches to a remote process with gdb-remote [PORT] and use Ctrl+D, it would kill the process instead of detach from it. rdar://156111423
1 parent bd9030e commit 322315b

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

lldb/source/Target/Process.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3256,6 +3256,7 @@ Status Process::ConnectRemote(llvm::StringRef remote_url) {
32563256
if (state == eStateStopped || state == eStateCrashed) {
32573257
// If we attached and actually have a process on the other end, then
32583258
// this ended up being the equivalent of an attach.
3259+
SetShouldDetach(true);
32593260
CompleteAttach();
32603261

32613262
// This delays passing the stopped event to listeners till
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""
2+
Test that ConnectRemote sets ShouldDetach flag correctly.
3+
4+
When connecting to a remote process that stops after connection,
5+
the process should be marked for detach (not kill) on destruction.
6+
"""
7+
8+
import lldb
9+
from lldbsuite.test.lldbtest import *
10+
from lldbsuite.test.decorators import *
11+
from lldbsuite.test.gdbclientutils import *
12+
from lldbsuite.test.lldbgdbclient import GDBRemoteTestBase
13+
from lldbsuite.test import lldbutil
14+
15+
16+
class TestConnectRemoteDetach(GDBRemoteTestBase):
17+
"""Test that ConnectRemote properly sets ShouldDetach flag."""
18+
19+
class StoppedResponder(MockGDBServerResponder):
20+
"""A responder that returns a stopped process."""
21+
22+
def qfThreadInfo(self):
23+
return "m1"
24+
25+
def qsThreadInfo(self):
26+
return "l"
27+
28+
def qC(self):
29+
return "QC1"
30+
31+
def haltReason(self):
32+
# Return that we're stopped
33+
return "T05thread:1;"
34+
35+
def cont(self):
36+
# Stay stopped
37+
return "T05thread:1;"
38+
39+
def D(self):
40+
# Detach packet - this is what we want to verify gets called
41+
return "OK"
42+
43+
def test_connect_remote_sets_detach(self):
44+
"""Test that ConnectRemote to a stopped process sets ShouldDetach."""
45+
self.server.responder = self.StoppedResponder()
46+
47+
target = self.createTarget("a.yaml")
48+
process = self.connect(target)
49+
50+
# Wait for the process to be in stopped state after connecting.
51+
# When ConnectRemote connects to a remote process that is stopped,
52+
# it should call SetShouldDetach(true) before CompleteAttach().
53+
lldbutil.expect_state_changes(
54+
self, self.dbg.GetListener(), process, [lldb.eStateStopped]
55+
)
56+
57+
# Now destroy the process. Because ShouldDetach was set to true
58+
# during ConnectRemote, this should send a 'D' (detach) packet
59+
# rather than a 'k' (kill) packet when the process is destroyed.
60+
process.Destroy()
61+
62+
# Verify that the detach packet was sent
63+
# The 'D' packet is the detach command in GDB remote protocol
64+
self.assertPacketLogReceived(["D"])

0 commit comments

Comments
 (0)