1 //===-- GDBRemoteClientBaseTest.cpp -----------------------------*- C++ -*-===// 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/StreamGDBRemote.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(data); 38 } 39 }; 40 41 struct TestClient : public GDBRemoteClientBase { 42 TestClient() : GDBRemoteClientBase("test.client", "test.client.listener") { 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 TestClient client; 59 MockServer server; 60 MockDelegate delegate; 61 ListenerSP listener_sp = Listener::MakeListener("listener"); 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->GetEventForBroadcasterWithType( 71 &client, TestClient::eBroadcastBitRunPacketSent, event_sp, llvm::None); 72 } 73 }; 74 75 } // end anonymous namespace 76 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 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 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 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 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 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 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 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 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 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