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 } 363