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     PacketResult
64     SendPacket(llvm::StringRef payload)
65     {
66         return GDBRemoteCommunicationServer::SendPacketNoLock(payload.data(), payload.size());
67     }
68 
69     PacketResult
70     GetPacket(StringExtractorGDBRemote &response)
71     {
72         const unsigned timeout_usec = 1000000; // 1s
73         const bool sync_on_timeout = false;
74         return WaitForPacketWithTimeoutMicroSecondsNoLock(response, timeout_usec, sync_on_timeout);
75     }
76 };
77 
78 struct TestClient : public GDBRemoteClientBase
79 {
80     TestClient() : GDBRemoteClientBase("test.client", "test.client.listener") { m_send_acks = false; }
81 };
82 
83 struct ContinueFixture
84 {
85     MockDelegate delegate;
86     TestClient client;
87     MockServer server;
88     ListenerSP listener_sp;
89 
90     ContinueFixture();
91 
92     StateType
93     SendCPacket(StringExtractorGDBRemote &response)
94     {
95         return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(), "c", response);
96     }
97 
98     void
99     WaitForRunEvent()
100     {
101         EventSP event_sp;
102         listener_sp->WaitForEventForBroadcasterWithType(std::chrono::microseconds(0), &client,
103                                                         TestClient::eBroadcastBitRunPacketSent, event_sp);
104     }
105 };
106 
107 ContinueFixture::ContinueFixture() : listener_sp(Listener::MakeListener("listener"))
108 {
109     bool child_processes_inherit = false;
110     Error error;
111     TCPSocket listen_socket(child_processes_inherit, error);
112     EXPECT_FALSE(error.Fail());
113     error = listen_socket.Listen("127.0.0.1:0", 5);
114     EXPECT_FALSE(error.Fail());
115 
116     Socket *accept_socket;
117     std::future<Error> accept_error = std::async(std::launch::async, [&] {
118         return listen_socket.Accept("127.0.0.1:0", child_processes_inherit, accept_socket);
119     });
120 
121     char connect_remote_address[64];
122     snprintf(connect_remote_address, sizeof(connect_remote_address), "connect://localhost:%u",
123              listen_socket.GetLocalPortNumber());
124 
125     std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
126     EXPECT_EQ(conn_ap->Connect(connect_remote_address, nullptr), lldb::eConnectionStatusSuccess);
127 
128     client.SetConnection(conn_ap.release());
129     EXPECT_TRUE(accept_error.get().Success());
130     server.SetConnection(new ConnectionFileDescriptor(accept_socket));
131 
132     listener_sp->StartListeningForEvents(&client, TestClient::eBroadcastBitRunPacketSent);
133 }
134 
135 } // end anonymous namespace
136 
137 class GDBRemoteClientBaseTest : public testing::Test
138 {
139 public:
140     static void
141     SetUpTestCase()
142     {
143 #if defined(_MSC_VER)
144         WSADATA data;
145         ::WSAStartup(MAKEWORD(2, 2), &data);
146 #endif
147     }
148 
149     static void
150     TearDownTestCase()
151     {
152 #if defined(_MSC_VER)
153         ::WSACleanup();
154 #endif
155     }
156 };
157 
158 TEST_F(GDBRemoteClientBaseTest, SendContinueAndWait)
159 {
160     StringExtractorGDBRemote response;
161     ContinueFixture fix;
162     if (HasFailure())
163         return;
164 
165     // Continue. The inferior will stop with a signal.
166     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
167     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
168     ASSERT_EQ("T01", response.GetStringRef());
169     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
170     ASSERT_EQ("c", response.GetStringRef());
171 
172     // Continue. The inferior will exit.
173     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("W01"));
174     ASSERT_EQ(eStateExited, fix.SendCPacket(response));
175     ASSERT_EQ("W01", response.GetStringRef());
176     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
177     ASSERT_EQ("c", response.GetStringRef());
178 
179     // Continue. The inferior will get killed.
180     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("X01"));
181     ASSERT_EQ(eStateExited, fix.SendCPacket(response));
182     ASSERT_EQ("X01", response.GetStringRef());
183     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
184     ASSERT_EQ("c", response.GetStringRef());
185 }
186 
187 TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncSignal)
188 {
189     StringExtractorGDBRemote continue_response, response;
190     ContinueFixture fix;
191     if (HasFailure())
192         return;
193 
194     // SendAsyncSignal should do nothing when we are not running.
195     ASSERT_FALSE(fix.client.SendAsyncSignal(0x47));
196 
197     // Continue. After the run packet is sent, send an async signal.
198     std::future<StateType> continue_state =
199         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
200     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
201     ASSERT_EQ("c", response.GetStringRef());
202     fix.WaitForRunEvent();
203 
204     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.SendAsyncSignal(0x47); });
205 
206     // First we'll get interrupted.
207     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
208     ASSERT_EQ("\x03", response.GetStringRef());
209     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
210 
211     // Then we get the signal packet.
212     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
213     ASSERT_EQ("C47", response.GetStringRef());
214     ASSERT_TRUE(async_result.get());
215 
216     // And we report back a signal stop.
217     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T47"));
218     ASSERT_EQ(eStateStopped, continue_state.get());
219     ASSERT_EQ("T47", continue_response.GetStringRef());
220 }
221 
222 TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncPacket)
223 {
224     StringExtractorGDBRemote continue_response, async_response, response;
225     const bool send_async = true;
226     ContinueFixture fix;
227     if (HasFailure())
228         return;
229 
230     // Continue. After the run packet is sent, send an async packet.
231     std::future<StateType> continue_state =
232         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
233     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
234     ASSERT_EQ("c", response.GetStringRef());
235     fix.WaitForRunEvent();
236 
237     // Sending without async enabled should fail.
238     ASSERT_EQ(PacketResult::ErrorSendFailed, fix.client.SendPacketAndWaitForResponse("qTest1", response, !send_async));
239 
240     std::future<PacketResult> async_result = std::async(std::launch::async, [&] {
241         return fix.client.SendPacketAndWaitForResponse("qTest2", async_response, send_async);
242     });
243 
244     // First we'll get interrupted.
245     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
246     ASSERT_EQ("\x03", response.GetStringRef());
247     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
248 
249     // Then we get the async packet.
250     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
251     ASSERT_EQ("qTest2", response.GetStringRef());
252 
253     // Send the response and receive it.
254     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest2"));
255     ASSERT_EQ(PacketResult::Success, async_result.get());
256     ASSERT_EQ("QTest2", async_response.GetStringRef());
257 
258     // And we get resumed again.
259     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
260     ASSERT_EQ("c", response.GetStringRef());
261     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
262     ASSERT_EQ(eStateStopped, continue_state.get());
263     ASSERT_EQ("T01", continue_response.GetStringRef());
264 }
265 
266 TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt)
267 {
268     StringExtractorGDBRemote continue_response, response;
269     ContinueFixture fix;
270     if (HasFailure())
271         return;
272 
273     // Interrupt should do nothing when we're not running.
274     ASSERT_FALSE(fix.client.Interrupt());
275 
276     // Continue. After the run packet is sent, send an interrupt.
277     std::future<StateType> continue_state =
278         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
279     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
280     ASSERT_EQ("c", response.GetStringRef());
281     fix.WaitForRunEvent();
282 
283     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
284 
285     // We get interrupted.
286     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
287     ASSERT_EQ("\x03", response.GetStringRef());
288     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
289 
290     // And that's it.
291     ASSERT_EQ(eStateStopped, continue_state.get());
292     ASSERT_EQ("T13", continue_response.GetStringRef());
293     ASSERT_TRUE(async_result.get());
294 }
295 
296 TEST_F(GDBRemoteClientBaseTest, SendContinueAndLateInterrupt)
297 {
298     StringExtractorGDBRemote continue_response, response;
299     ContinueFixture fix;
300     if (HasFailure())
301         return;
302 
303     // Continue. After the run packet is sent, send an interrupt.
304     std::future<StateType> continue_state =
305         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
306     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
307     ASSERT_EQ("c", response.GetStringRef());
308     fix.WaitForRunEvent();
309 
310     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
311 
312     // However, the target stops due to a different reason than the original interrupt.
313     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
314     ASSERT_EQ("\x03", response.GetStringRef());
315     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
316     ASSERT_EQ(eStateStopped, continue_state.get());
317     ASSERT_EQ("T01", continue_response.GetStringRef());
318     ASSERT_TRUE(async_result.get());
319 
320     // The subsequent continue packet should work normally.
321     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
322     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
323     ASSERT_EQ("T01", response.GetStringRef());
324     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
325     ASSERT_EQ("c", response.GetStringRef());
326 }
327 
328 TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug)
329 {
330     StringExtractorGDBRemote continue_response, async_response, response;
331     const bool send_async = true;
332     ContinueFixture fix;
333     if (HasFailure())
334         return;
335 
336     // Interrupt should do nothing when we're not running.
337     ASSERT_FALSE(fix.client.Interrupt());
338 
339     // Continue. After the run packet is sent, send an async signal.
340     std::future<StateType> continue_state =
341         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
342     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
343     ASSERT_EQ("c", response.GetStringRef());
344     fix.WaitForRunEvent();
345 
346     std::future<bool> interrupt_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
347 
348     // We get interrupted. We'll send two packets to simulate a buggy stub.
349     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
350     ASSERT_EQ("\x03", response.GetStringRef());
351     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
352     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
353 
354     // We should stop.
355     ASSERT_EQ(eStateStopped, continue_state.get());
356     ASSERT_EQ("T13", continue_response.GetStringRef());
357     ASSERT_TRUE(interrupt_result.get());
358 
359     // Packet stream should remain synchronized.
360     std::future<PacketResult> send_result = std::async(std::launch::async, [&] {
361         return fix.client.SendPacketAndWaitForResponse("qTest", async_response, !send_async);
362     });
363     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
364     ASSERT_EQ("qTest", response.GetStringRef());
365     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest"));
366     ASSERT_EQ(PacketResult::Success, send_result.get());
367     ASSERT_EQ("QTest", async_response.GetStringRef());
368 }
369 
370 TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateInterface)
371 {
372     StringExtractorGDBRemote response;
373     ContinueFixture fix;
374     if (HasFailure())
375         return;
376 
377     // Continue. We'll have the server send a bunch of async packets before it stops.
378     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4142"));
379     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Apro"));
380     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4344"));
381     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Afile"));
382     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
383     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
384     ASSERT_EQ("T01", response.GetStringRef());
385     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
386     ASSERT_EQ("c", response.GetStringRef());
387 
388     EXPECT_EQ("ABCD", fix.delegate.output);
389     EXPECT_EQ("profile", fix.delegate.misc_data);
390     EXPECT_EQ(1u, fix.delegate.stop_reply_called);
391 }
392 
393 TEST_F(GDBRemoteClientBaseTest, InterruptNoResponse)
394 {
395     StringExtractorGDBRemote continue_response, response;
396     ContinueFixture fix;
397     if (HasFailure())
398         return;
399 
400     // Continue. After the run packet is sent, send an interrupt.
401     std::future<StateType> continue_state =
402         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
403     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
404     ASSERT_EQ("c", response.GetStringRef());
405     fix.WaitForRunEvent();
406 
407     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
408 
409     // We get interrupted, but we don't send a stop packet.
410     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
411     ASSERT_EQ("\x03", response.GetStringRef());
412 
413     // The functions should still terminate (after a timeout).
414     ASSERT_TRUE(async_result.get());
415     ASSERT_EQ(eStateInvalid, continue_state.get());
416 }
417