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