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__anon7c812b550111::MockDelegate32 void HandleAsyncStdout(llvm::StringRef out) override { output += out; }
HandleAsyncMisc__anon7c812b550111::MockDelegate33 void HandleAsyncMisc(llvm::StringRef data) override { misc_data += data; }
HandleStopReply__anon7c812b550111::MockDelegate34 void HandleStopReply() override { ++stop_reply_called; }
35
HandleAsyncStructuredDataPacket__anon7c812b550111::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__anon7c812b550111::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 // 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
SendCPacket(StringExtractorGDBRemote & response)65 StateType SendCPacket(StringExtractorGDBRemote &response) {
66 return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(),
67 "c", g_timeout,
68 response);
69 }
70
WaitForRunEvent()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
TEST_F(GDBRemoteClientBaseTest,SendContinueAndWait)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
TEST_F(GDBRemoteClientBaseTest,SendContinueAndAsyncSignal)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
TEST_F(GDBRemoteClientBaseTest,SendContinueAndAsyncPacket)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
TEST_F(GDBRemoteClientBaseTest,SendContinueAndInterrupt)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
TEST_F(GDBRemoteClientBaseTest,SendContinueAndLateInterrupt)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
TEST_F(GDBRemoteClientBaseTest,SendContinueAndInterrupt2PacketBug)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
TEST_F(GDBRemoteClientBaseTest,SendContinueDelegateInterface)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
TEST_F(GDBRemoteClientBaseTest,SendContinueDelegateStructuredDataReceipt)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
TEST_F(GDBRemoteClientBaseTest,InterruptNoResponse)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
TEST_F(GDBRemoteClientBaseTest,SendPacketAndReceiveResponseWithOutputSupport)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