xref: /llvm-project/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp (revision 8c1b6bd7d2ac9c4a1a017405959185978204c5d5)
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_F(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_F(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_F(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_F(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_F(GDBRemoteClientBaseTest, SendContinueAndLateInterrupt)
309 {
310     StringExtractorGDBRemote continue_response, response;
311     ContinueFixture fix;
312     if (HasFailure())
313         return;
314 
315     // Continue. After the run packet is sent, send an interrupt.
316     std::future<StateType> continue_state =
317         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
318     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
319     ASSERT_EQ("c", response.GetStringRef());
320     fix.WaitForRunEvent();
321 
322     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
323 
324     // However, the target stops due to a different reason than the original interrupt.
325     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
326     ASSERT_EQ("\x03", response.GetStringRef());
327     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
328     ASSERT_EQ(eStateStopped, continue_state.get());
329     ASSERT_EQ("T01", continue_response.GetStringRef());
330     ASSERT_TRUE(async_result.get());
331 
332     // The subsequent continue packet should work normally.
333     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
334     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
335     ASSERT_EQ("T01", response.GetStringRef());
336     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
337     ASSERT_EQ("c", response.GetStringRef());
338 }
339 
340 TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug)
341 {
342     StringExtractorGDBRemote continue_response, async_response, response;
343     const bool send_async = true;
344     ContinueFixture fix;
345     if (HasFailure())
346         return;
347 
348     // Interrupt should do nothing when we're not running.
349     ASSERT_FALSE(fix.client.Interrupt());
350 
351     // Continue. After the run packet is sent, send an async signal.
352     std::future<StateType> continue_state =
353         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
354     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
355     ASSERT_EQ("c", response.GetStringRef());
356     fix.WaitForRunEvent();
357 
358     std::future<bool> interrupt_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
359 
360     // We get interrupted. We'll send two packets to simulate a buggy stub.
361     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
362     ASSERT_EQ("\x03", response.GetStringRef());
363     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
364     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
365 
366     // We should stop.
367     ASSERT_EQ(eStateStopped, continue_state.get());
368     ASSERT_EQ("T13", continue_response.GetStringRef());
369     ASSERT_TRUE(interrupt_result.get());
370 
371     // Packet stream should remain synchronized.
372     std::future<PacketResult> send_result = std::async(std::launch::async, [&] {
373         return fix.client.SendPacketAndWaitForResponse("qTest", async_response, !send_async);
374     });
375     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
376     ASSERT_EQ("qTest", response.GetStringRef());
377     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest"));
378     ASSERT_EQ(PacketResult::Success, send_result.get());
379     ASSERT_EQ("QTest", async_response.GetStringRef());
380 }
381 
382 TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateInterface)
383 {
384     StringExtractorGDBRemote response;
385     ContinueFixture fix;
386     if (HasFailure())
387         return;
388 
389     // Continue. We'll have the server send a bunch of async packets before it stops.
390     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4142"));
391     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Apro"));
392     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4344"));
393     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Afile"));
394     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
395     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
396     ASSERT_EQ("T01", response.GetStringRef());
397     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
398     ASSERT_EQ("c", response.GetStringRef());
399 
400     EXPECT_EQ("ABCD", fix.delegate.output);
401     EXPECT_EQ("profile", fix.delegate.misc_data);
402     EXPECT_EQ(1u, fix.delegate.stop_reply_called);
403 }
404 
405 TEST_F(GDBRemoteClientBaseTest, InterruptNoResponse)
406 {
407     StringExtractorGDBRemote continue_response, response;
408     ContinueFixture fix;
409     if (HasFailure())
410         return;
411 
412     // Continue. After the run packet is sent, send an interrupt.
413     std::future<StateType> continue_state =
414         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
415     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
416     ASSERT_EQ("c", response.GetStringRef());
417     fix.WaitForRunEvent();
418 
419     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
420 
421     // We get interrupted, but we don't send a stop packet.
422     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
423     ASSERT_EQ("\x03", response.GetStringRef());
424 
425     // The functions should still terminate (after a timeout).
426     ASSERT_TRUE(async_result.get());
427     ASSERT_EQ(eStateInvalid, continue_state.get());
428 }
429