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