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