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