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