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