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