xref: /llvm-project/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp (revision e768c4b858bd32b814baf142dd2acfeae6022638)
1 //===-- GDBRemoteClientBaseTest.cpp -----------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
11 // Workaround for MSVC standard library bug, which fails to include <thread> when
12 // exceptions are disabled.
13 #include <eh.h>
14 #endif
15 #include <future>
16 
17 #include "gtest/gtest.h"
18 
19 #include "Plugins/Process/Utility/LinuxSignals.h"
20 #include "Plugins/Process/gdb-remote/GDBRemoteClientBase.h"
21 #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
22 
23 #include "lldb/Host/common/TCPSocket.h"
24 #include "lldb/Host/posix/ConnectionFileDescriptorPosix.h"
25 
26 #include "llvm/ADT/STLExtras.h"
27 
28 using namespace lldb_private::process_gdb_remote;
29 using namespace lldb_private;
30 using namespace lldb;
31 typedef GDBRemoteCommunication::PacketResult PacketResult;
32 
33 namespace
34 {
35 
36 struct MockDelegate : public GDBRemoteClientBase::ContinueDelegate
37 {
38     std::string output;
39     std::string misc_data;
40     unsigned stop_reply_called = 0;
41 
42     void
43     HandleAsyncStdout(llvm::StringRef out)
44     {
45         output += out;
46     }
47     void
48     HandleAsyncMisc(llvm::StringRef data)
49     {
50         misc_data += data;
51     }
52     void
53     HandleStopReply()
54     {
55         ++stop_reply_called;
56     }
57 };
58 
59 struct MockServer : public GDBRemoteCommunicationServer
60 {
61     MockServer() : GDBRemoteCommunicationServer("mock-server", "mock-server.listener") { m_send_acks = false; }
62 
63     bool
64     GetThreadSuffixSupported() override
65     {
66         return false;
67     }
68 
69     PacketResult
70     SendPacket(llvm::StringRef payload)
71     {
72         return GDBRemoteCommunicationServer::SendPacketNoLock(payload.data(), payload.size());
73     }
74 
75     PacketResult
76     GetPacket(StringExtractorGDBRemote &response)
77     {
78         const unsigned timeout_usec = 1000000; // 1s
79         const bool sync_on_timeout = false;
80         return WaitForPacketWithTimeoutMicroSecondsNoLock(response, timeout_usec, sync_on_timeout);
81     }
82 };
83 
84 struct TestClient : public GDBRemoteClientBase
85 {
86     TestClient() : GDBRemoteClientBase("test.client", "test.client.listener") { m_send_acks = false; }
87 
88     bool
89     GetThreadSuffixSupported() override
90     {
91         return false;
92     }
93 };
94 
95 struct ContinueFixture
96 {
97     MockDelegate delegate;
98     TestClient client;
99     MockServer server;
100     ListenerSP listener_sp;
101 
102     ContinueFixture();
103 
104     StateType
105     SendCPacket(StringExtractorGDBRemote &response)
106     {
107         return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(), "c", response);
108     }
109 
110     void
111     WaitForRunEvent()
112     {
113         EventSP event_sp;
114         listener_sp->WaitForEventForBroadcasterWithType(std::chrono::microseconds(0), &client,
115                                                         TestClient::eBroadcastBitRunPacketSent, event_sp);
116     }
117 };
118 
119 ContinueFixture::ContinueFixture() : listener_sp(Listener::MakeListener("listener"))
120 {
121     bool child_processes_inherit = false;
122     Error error;
123     TCPSocket listen_socket(child_processes_inherit, error);
124     EXPECT_FALSE(error.Fail());
125     error = listen_socket.Listen("127.0.0.1:0", 5);
126     EXPECT_FALSE(error.Fail());
127 
128     Socket *accept_socket;
129     std::future<Error> accept_error = std::async(std::launch::async, [&] {
130         return listen_socket.Accept("127.0.0.1:0", child_processes_inherit, accept_socket);
131     });
132 
133     char connect_remote_address[64];
134     snprintf(connect_remote_address, sizeof(connect_remote_address), "connect://localhost:%u",
135              listen_socket.GetLocalPortNumber());
136 
137     std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
138     EXPECT_EQ(conn_ap->Connect(connect_remote_address, nullptr), lldb::eConnectionStatusSuccess);
139 
140     client.SetConnection(conn_ap.release());
141     EXPECT_TRUE(accept_error.get().Success());
142     server.SetConnection(new ConnectionFileDescriptor(accept_socket));
143 
144     listener_sp->StartListeningForEvents(&client, TestClient::eBroadcastBitRunPacketSent);
145 }
146 
147 } // end anonymous namespace
148 
149 class GDBRemoteClientBaseTest : public testing::Test
150 {
151 public:
152     static void
153     SetUpTestCase()
154     {
155 #if defined(_MSC_VER)
156         WSADATA data;
157         ::WSAStartup(MAKEWORD(2, 2), &data);
158 #endif
159     }
160 
161     static void
162     TearDownTestCase()
163     {
164 #if defined(_MSC_VER)
165         ::WSACleanup();
166 #endif
167     }
168 };
169 
170 TEST(GDBRemoteClientBaseTest, SendContinueAndWait)
171 {
172     StringExtractorGDBRemote response;
173     ContinueFixture fix;
174     if (HasFailure())
175         return;
176 
177     // Continue. The inferior will stop with a signal.
178     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
179     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
180     ASSERT_EQ("T01", response.GetStringRef());
181     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
182     ASSERT_EQ("c", response.GetStringRef());
183 
184     // Continue. The inferior will exit.
185     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("W01"));
186     ASSERT_EQ(eStateExited, fix.SendCPacket(response));
187     ASSERT_EQ("W01", response.GetStringRef());
188     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
189     ASSERT_EQ("c", response.GetStringRef());
190 
191     // Continue. The inferior will get killed.
192     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("X01"));
193     ASSERT_EQ(eStateExited, fix.SendCPacket(response));
194     ASSERT_EQ("X01", response.GetStringRef());
195     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
196     ASSERT_EQ("c", response.GetStringRef());
197 }
198 
199 TEST(GDBRemoteClientBaseTest, SendContinueAndAsyncSignal)
200 {
201     StringExtractorGDBRemote continue_response, response;
202     ContinueFixture fix;
203     if (HasFailure())
204         return;
205 
206     // SendAsyncSignal should do nothing when we are not running.
207     ASSERT_FALSE(fix.client.SendAsyncSignal(0x47));
208 
209     // Continue. After the run packet is sent, send an async signal.
210     std::future<StateType> continue_state =
211         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
212     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
213     ASSERT_EQ("c", response.GetStringRef());
214     fix.WaitForRunEvent();
215 
216     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.SendAsyncSignal(0x47); });
217 
218     // First we'll get interrupted.
219     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
220     ASSERT_EQ("\x03", response.GetStringRef());
221     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
222 
223     // Then we get the signal packet.
224     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
225     ASSERT_EQ("C47", response.GetStringRef());
226     ASSERT_TRUE(async_result.get());
227 
228     // And we report back a signal stop.
229     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T47"));
230     ASSERT_EQ(eStateStopped, continue_state.get());
231     ASSERT_EQ("T47", continue_response.GetStringRef());
232 }
233 
234 TEST(GDBRemoteClientBaseTest, SendContinueAndAsyncPacket)
235 {
236     StringExtractorGDBRemote continue_response, async_response, response;
237     const bool send_async = true;
238     ContinueFixture fix;
239     if (HasFailure())
240         return;
241 
242     // Continue. After the run packet is sent, send an async packet.
243     std::future<StateType> continue_state =
244         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
245     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
246     ASSERT_EQ("c", response.GetStringRef());
247     fix.WaitForRunEvent();
248 
249     // Sending without async enabled should fail.
250     ASSERT_EQ(PacketResult::ErrorSendFailed, fix.client.SendPacketAndWaitForResponse("qTest1", response, !send_async));
251 
252     std::future<PacketResult> async_result = std::async(std::launch::async, [&] {
253         return fix.client.SendPacketAndWaitForResponse("qTest2", async_response, send_async);
254     });
255 
256     // First we'll get interrupted.
257     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
258     ASSERT_EQ("\x03", response.GetStringRef());
259     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
260 
261     // Then we get the async packet.
262     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
263     ASSERT_EQ("qTest2", response.GetStringRef());
264 
265     // Send the response and receive it.
266     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest2"));
267     ASSERT_EQ(PacketResult::Success, async_result.get());
268     ASSERT_EQ("QTest2", async_response.GetStringRef());
269 
270     // And we get resumed again.
271     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
272     ASSERT_EQ("c", response.GetStringRef());
273     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
274     ASSERT_EQ(eStateStopped, continue_state.get());
275     ASSERT_EQ("T01", continue_response.GetStringRef());
276 }
277 
278 TEST(GDBRemoteClientBaseTest, SendContinueAndInterrupt)
279 {
280     StringExtractorGDBRemote continue_response, response;
281     ContinueFixture fix;
282     if (HasFailure())
283         return;
284 
285     // Interrupt should do nothing when we're not running.
286     ASSERT_FALSE(fix.client.Interrupt());
287 
288     // Continue. After the run packet is sent, send an interrupt.
289     std::future<StateType> continue_state =
290         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
291     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
292     ASSERT_EQ("c", response.GetStringRef());
293     fix.WaitForRunEvent();
294 
295     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
296 
297     // We get interrupted.
298     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
299     ASSERT_EQ("\x03", response.GetStringRef());
300     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
301 
302     // And that's it.
303     ASSERT_EQ(eStateStopped, continue_state.get());
304     ASSERT_EQ("T13", continue_response.GetStringRef());
305     ASSERT_TRUE(async_result.get());
306 }
307 
308 TEST(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug)
309 {
310     StringExtractorGDBRemote continue_response, async_response, response;
311     const bool send_async = true;
312     ContinueFixture fix;
313     if (HasFailure())
314         return;
315 
316     // Interrupt should do nothing when we're not running.
317     ASSERT_FALSE(fix.client.Interrupt());
318 
319     // Continue. After the run packet is sent, send an async signal.
320     std::future<StateType> continue_state =
321         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
322     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
323     ASSERT_EQ("c", response.GetStringRef());
324     fix.WaitForRunEvent();
325 
326     std::future<bool> interrupt_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
327 
328     // We get interrupted. We'll send two packets to simulate a buggy stub.
329     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
330     ASSERT_EQ("\x03", response.GetStringRef());
331     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
332     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
333 
334     // We should stop.
335     ASSERT_EQ(eStateStopped, continue_state.get());
336     ASSERT_EQ("T13", continue_response.GetStringRef());
337     ASSERT_TRUE(interrupt_result.get());
338 
339     // Packet stream should remain synchronized.
340     std::future<PacketResult> send_result = std::async(std::launch::async, [&] {
341         return fix.client.SendPacketAndWaitForResponse("qTest", async_response, !send_async);
342     });
343     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
344     ASSERT_EQ("qTest", response.GetStringRef());
345     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest"));
346     ASSERT_EQ(PacketResult::Success, send_result.get());
347     ASSERT_EQ("QTest", async_response.GetStringRef());
348 }
349 
350 TEST(GDBRemoteClientBaseTest, SendContinueDelegateInterface)
351 {
352     StringExtractorGDBRemote response;
353     ContinueFixture fix;
354     if (HasFailure())
355         return;
356 
357     // Continue. We'll have the server send a bunch of async packets before it stops.
358     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4142"));
359     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Apro"));
360     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4344"));
361     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Afile"));
362     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
363     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
364     ASSERT_EQ("T01", response.GetStringRef());
365     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
366     ASSERT_EQ("c", response.GetStringRef());
367 
368     EXPECT_EQ("ABCD", fix.delegate.output);
369     EXPECT_EQ("profile", fix.delegate.misc_data);
370     EXPECT_EQ(1u, fix.delegate.stop_reply_called);
371 }
372 
373 TEST(GDBRemoteClientBaseTest, InterruptNoResponse)
374 {
375     StringExtractorGDBRemote continue_response, response;
376     ContinueFixture fix;
377     if (HasFailure())
378         return;
379 
380     // Continue. After the run packet is sent, send an interrupt.
381     std::future<StateType> continue_state =
382         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
383     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
384     ASSERT_EQ("c", response.GetStringRef());
385     fix.WaitForRunEvent();
386 
387     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
388 
389     // We get interrupted, but we don't send a stop packet.
390     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
391     ASSERT_EQ("\x03", response.GetStringRef());
392 
393     // The functions should still terminate (after a timeout).
394     ASSERT_TRUE(async_result.get());
395     ASSERT_EQ(eStateInvalid, continue_state.get());
396 }
397