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