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