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