xref: /llvm-project/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp (revision 49178e5efee844ba2a9ea6b2877e8b0ceadc1a8b)
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 "GDBRemoteTestUtils.h"
18 #include "gtest/gtest.h"
19 
20 #include "Plugins/Process/Utility/LinuxSignals.h"
21 #include "Plugins/Process/gdb-remote/GDBRemoteClientBase.h"
22 #include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
23 
24 #include "llvm/ADT/STLExtras.h"
25 
26 using namespace lldb_private::process_gdb_remote;
27 using namespace lldb_private;
28 using namespace lldb;
29 typedef GDBRemoteCommunication::PacketResult PacketResult;
30 
31 namespace
32 {
33 
34 struct MockDelegate : public GDBRemoteClientBase::ContinueDelegate
35 {
36     std::string output;
37     std::string misc_data;
38     unsigned stop_reply_called = 0;
39 
40     void
41     HandleAsyncStdout(llvm::StringRef out)
42     {
43         output += out;
44     }
45     void
46     HandleAsyncMisc(llvm::StringRef data)
47     {
48         misc_data += data;
49     }
50     void
51     HandleStopReply()
52     {
53         ++stop_reply_called;
54     }
55 
56     bool
57     HandleAsyncStructuredData(const StructuredData::ObjectSP
58                               &object_sp)
59     {
60         // TODO work in a test here after I fix the gtest breakage.
61         return true;
62     }
63 
64 };
65 
66 struct TestClient : public GDBRemoteClientBase
67 {
68     TestClient() : GDBRemoteClientBase("test.client", "test.client.listener") { m_send_acks = false; }
69 };
70 
71 struct ContinueFixture
72 {
73     MockDelegate delegate;
74     TestClient client;
75     MockServer server;
76     ListenerSP listener_sp;
77 
78     ContinueFixture();
79 
80     StateType
81     SendCPacket(StringExtractorGDBRemote &response)
82     {
83         return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(), "c", response);
84     }
85 
86     void
87     WaitForRunEvent()
88     {
89         EventSP event_sp;
90         listener_sp->WaitForEventForBroadcasterWithType(std::chrono::microseconds(0), &client,
91                                                         TestClient::eBroadcastBitRunPacketSent, event_sp);
92     }
93 };
94 
95 ContinueFixture::ContinueFixture() : listener_sp(Listener::MakeListener("listener"))
96 {
97     Connect(client, server);
98     listener_sp->StartListeningForEvents(&client, TestClient::eBroadcastBitRunPacketSent);
99 }
100 
101 } // end anonymous namespace
102 
103 class GDBRemoteClientBaseTest : public GDBRemoteTest
104 {
105 };
106 
107 TEST_F(GDBRemoteClientBaseTest, SendContinueAndWait)
108 {
109     StringExtractorGDBRemote response;
110     ContinueFixture fix;
111     if (HasFailure())
112         return;
113 
114     // Continue. The inferior will stop with a signal.
115     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
116     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
117     ASSERT_EQ("T01", response.GetStringRef());
118     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
119     ASSERT_EQ("c", response.GetStringRef());
120 
121     // Continue. The inferior will exit.
122     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("W01"));
123     ASSERT_EQ(eStateExited, fix.SendCPacket(response));
124     ASSERT_EQ("W01", response.GetStringRef());
125     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
126     ASSERT_EQ("c", response.GetStringRef());
127 
128     // Continue. The inferior will get killed.
129     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("X01"));
130     ASSERT_EQ(eStateExited, fix.SendCPacket(response));
131     ASSERT_EQ("X01", response.GetStringRef());
132     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
133     ASSERT_EQ("c", response.GetStringRef());
134 }
135 
136 TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncSignal)
137 {
138     StringExtractorGDBRemote continue_response, response;
139     ContinueFixture fix;
140     if (HasFailure())
141         return;
142 
143     // SendAsyncSignal should do nothing when we are not running.
144     ASSERT_FALSE(fix.client.SendAsyncSignal(0x47));
145 
146     // Continue. After the run packet is sent, send an async signal.
147     std::future<StateType> continue_state =
148         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
149     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
150     ASSERT_EQ("c", response.GetStringRef());
151     fix.WaitForRunEvent();
152 
153     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.SendAsyncSignal(0x47); });
154 
155     // First we'll get interrupted.
156     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
157     ASSERT_EQ("\x03", response.GetStringRef());
158     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
159 
160     // Then we get the signal packet.
161     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
162     ASSERT_EQ("C47", response.GetStringRef());
163     ASSERT_TRUE(async_result.get());
164 
165     // And we report back a signal stop.
166     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T47"));
167     ASSERT_EQ(eStateStopped, continue_state.get());
168     ASSERT_EQ("T47", continue_response.GetStringRef());
169 }
170 
171 TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncPacket)
172 {
173     StringExtractorGDBRemote continue_response, async_response, response;
174     const bool send_async = true;
175     ContinueFixture fix;
176     if (HasFailure())
177         return;
178 
179     // Continue. After the run packet is sent, send an async packet.
180     std::future<StateType> continue_state =
181         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
182     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
183     ASSERT_EQ("c", response.GetStringRef());
184     fix.WaitForRunEvent();
185 
186     // Sending without async enabled should fail.
187     ASSERT_EQ(PacketResult::ErrorSendFailed, fix.client.SendPacketAndWaitForResponse("qTest1", response, !send_async));
188 
189     std::future<PacketResult> async_result = std::async(std::launch::async, [&] {
190         return fix.client.SendPacketAndWaitForResponse("qTest2", async_response, send_async);
191     });
192 
193     // First we'll get interrupted.
194     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
195     ASSERT_EQ("\x03", response.GetStringRef());
196     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
197 
198     // Then we get the async packet.
199     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
200     ASSERT_EQ("qTest2", response.GetStringRef());
201 
202     // Send the response and receive it.
203     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest2"));
204     ASSERT_EQ(PacketResult::Success, async_result.get());
205     ASSERT_EQ("QTest2", async_response.GetStringRef());
206 
207     // And we get resumed again.
208     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
209     ASSERT_EQ("c", response.GetStringRef());
210     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
211     ASSERT_EQ(eStateStopped, continue_state.get());
212     ASSERT_EQ("T01", continue_response.GetStringRef());
213 }
214 
215 TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt)
216 {
217     StringExtractorGDBRemote continue_response, response;
218     ContinueFixture fix;
219     if (HasFailure())
220         return;
221 
222     // Interrupt should do nothing when we're not running.
223     ASSERT_FALSE(fix.client.Interrupt());
224 
225     // Continue. After the run packet is sent, send an interrupt.
226     std::future<StateType> continue_state =
227         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
228     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
229     ASSERT_EQ("c", response.GetStringRef());
230     fix.WaitForRunEvent();
231 
232     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
233 
234     // We get interrupted.
235     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
236     ASSERT_EQ("\x03", response.GetStringRef());
237     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
238 
239     // And that's it.
240     ASSERT_EQ(eStateStopped, continue_state.get());
241     ASSERT_EQ("T13", continue_response.GetStringRef());
242     ASSERT_TRUE(async_result.get());
243 }
244 
245 TEST_F(GDBRemoteClientBaseTest, SendContinueAndLateInterrupt)
246 {
247     StringExtractorGDBRemote continue_response, response;
248     ContinueFixture fix;
249     if (HasFailure())
250         return;
251 
252     // Continue. After the run packet is sent, send an interrupt.
253     std::future<StateType> continue_state =
254         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
255     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
256     ASSERT_EQ("c", response.GetStringRef());
257     fix.WaitForRunEvent();
258 
259     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
260 
261     // However, the target stops due to a different reason than the original interrupt.
262     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
263     ASSERT_EQ("\x03", response.GetStringRef());
264     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
265     ASSERT_EQ(eStateStopped, continue_state.get());
266     ASSERT_EQ("T01", continue_response.GetStringRef());
267     ASSERT_TRUE(async_result.get());
268 
269     // The subsequent continue packet should work normally.
270     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
271     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
272     ASSERT_EQ("T01", response.GetStringRef());
273     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
274     ASSERT_EQ("c", response.GetStringRef());
275 }
276 
277 TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug)
278 {
279     StringExtractorGDBRemote continue_response, async_response, response;
280     const bool send_async = true;
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 async signal.
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> interrupt_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
296 
297     // We get interrupted. We'll send two packets to simulate a buggy stub.
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     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
302 
303     // We should stop.
304     ASSERT_EQ(eStateStopped, continue_state.get());
305     ASSERT_EQ("T13", continue_response.GetStringRef());
306     ASSERT_TRUE(interrupt_result.get());
307 
308     // Packet stream should remain synchronized.
309     std::future<PacketResult> send_result = std::async(std::launch::async, [&] {
310         return fix.client.SendPacketAndWaitForResponse("qTest", async_response, !send_async);
311     });
312     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
313     ASSERT_EQ("qTest", response.GetStringRef());
314     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest"));
315     ASSERT_EQ(PacketResult::Success, send_result.get());
316     ASSERT_EQ("QTest", async_response.GetStringRef());
317 }
318 
319 TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateInterface)
320 {
321     StringExtractorGDBRemote response;
322     ContinueFixture fix;
323     if (HasFailure())
324         return;
325 
326     // Continue. We'll have the server send a bunch of async packets before it stops.
327     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4142"));
328     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Apro"));
329     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4344"));
330     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Afile"));
331     ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
332     ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
333     ASSERT_EQ("T01", response.GetStringRef());
334     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
335     ASSERT_EQ("c", response.GetStringRef());
336 
337     EXPECT_EQ("ABCD", fix.delegate.output);
338     EXPECT_EQ("profile", fix.delegate.misc_data);
339     EXPECT_EQ(1u, fix.delegate.stop_reply_called);
340 }
341 
342 TEST_F(GDBRemoteClientBaseTest, InterruptNoResponse)
343 {
344     StringExtractorGDBRemote continue_response, response;
345     ContinueFixture fix;
346     if (HasFailure())
347         return;
348 
349     // Continue. After the run packet is sent, send an interrupt.
350     std::future<StateType> continue_state =
351         std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
352     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
353     ASSERT_EQ("c", response.GetStringRef());
354     fix.WaitForRunEvent();
355 
356     std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
357 
358     // We get interrupted, but we don't send a stop packet.
359     ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
360     ASSERT_EQ("\x03", response.GetStringRef());
361 
362     // The functions should still terminate (after a timeout).
363     ASSERT_TRUE(async_result.get());
364     ASSERT_EQ(eStateInvalid, continue_state.get());
365 }
366