aboutsummaryrefslogtreecommitdiff
path: root/lldb/unittests/Process/gdb-remote
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/unittests/Process/gdb-remote')
-rw-r--r--lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp603
-rw-r--r--lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp258
-rw-r--r--lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp66
-rw-r--r--lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h61
4 files changed, 482 insertions, 506 deletions
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
index 6b56e5c..6039794 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteClientBaseTest.cpp
@@ -8,7 +8,8 @@
//===----------------------------------------------------------------------===//
#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread> when
+// Workaround for MSVC standard library bug, which fails to include <thread>
+// when
// exceptions are disabled.
#include <eh.h>
#endif
@@ -28,338 +29,320 @@ using namespace lldb_private;
using namespace lldb;
typedef GDBRemoteCommunication::PacketResult PacketResult;
-namespace
-{
-
-struct MockDelegate : public GDBRemoteClientBase::ContinueDelegate
-{
- std::string output;
- std::string misc_data;
- unsigned stop_reply_called = 0;
-
- void
- HandleAsyncStdout(llvm::StringRef out)
- {
- output += out;
- }
- void
- HandleAsyncMisc(llvm::StringRef data)
- {
- misc_data += data;
- }
- void
- HandleStopReply()
- {
- ++stop_reply_called;
- }
-
- bool
- HandleAsyncStructuredData(const StructuredData::ObjectSP
- &object_sp)
- {
- // TODO work in a test here after I fix the gtest breakage.
- return true;
- }
+namespace {
+struct MockDelegate : public GDBRemoteClientBase::ContinueDelegate {
+ std::string output;
+ std::string misc_data;
+ unsigned stop_reply_called = 0;
+
+ void HandleAsyncStdout(llvm::StringRef out) { output += out; }
+ void HandleAsyncMisc(llvm::StringRef data) { misc_data += data; }
+ void HandleStopReply() { ++stop_reply_called; }
+
+ bool HandleAsyncStructuredData(const StructuredData::ObjectSP &object_sp) {
+ // TODO work in a test here after I fix the gtest breakage.
+ return true;
+ }
};
-struct TestClient : public GDBRemoteClientBase
-{
- TestClient() : GDBRemoteClientBase("test.client", "test.client.listener") { m_send_acks = false; }
+struct TestClient : public GDBRemoteClientBase {
+ TestClient() : GDBRemoteClientBase("test.client", "test.client.listener") {
+ m_send_acks = false;
+ }
};
-struct ContinueFixture
-{
- MockDelegate delegate;
- TestClient client;
- MockServer server;
- ListenerSP listener_sp;
-
- ContinueFixture();
-
- StateType
- SendCPacket(StringExtractorGDBRemote &response)
- {
- return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(), "c", response);
- }
-
- void
- WaitForRunEvent()
- {
- EventSP event_sp;
- listener_sp->WaitForEventForBroadcasterWithType(std::chrono::microseconds(0), &client,
- TestClient::eBroadcastBitRunPacketSent, event_sp);
- }
+struct ContinueFixture {
+ MockDelegate delegate;
+ TestClient client;
+ MockServer server;
+ ListenerSP listener_sp;
+
+ ContinueFixture();
+
+ StateType SendCPacket(StringExtractorGDBRemote &response) {
+ return client.SendContinuePacketAndWaitForResponse(delegate, LinuxSignals(),
+ "c", response);
+ }
+
+ void WaitForRunEvent() {
+ EventSP event_sp;
+ listener_sp->WaitForEventForBroadcasterWithType(
+ std::chrono::microseconds(0), &client,
+ TestClient::eBroadcastBitRunPacketSent, event_sp);
+ }
};
-ContinueFixture::ContinueFixture() : listener_sp(Listener::MakeListener("listener"))
-{
- Connect(client, server);
- listener_sp->StartListeningForEvents(&client, TestClient::eBroadcastBitRunPacketSent);
+ContinueFixture::ContinueFixture()
+ : listener_sp(Listener::MakeListener("listener")) {
+ Connect(client, server);
+ listener_sp->StartListeningForEvents(&client,
+ TestClient::eBroadcastBitRunPacketSent);
}
} // end anonymous namespace
-class GDBRemoteClientBaseTest : public GDBRemoteTest
-{
-};
-
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndWait)
-{
- StringExtractorGDBRemote response;
- ContinueFixture fix;
- if (HasFailure())
- return;
-
- // Continue. The inferior will stop with a signal.
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
-
- // Continue. The inferior will exit.
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("W01"));
- ASSERT_EQ(eStateExited, fix.SendCPacket(response));
- ASSERT_EQ("W01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
-
- // Continue. The inferior will get killed.
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("X01"));
- ASSERT_EQ(eStateExited, fix.SendCPacket(response));
- ASSERT_EQ("X01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+class GDBRemoteClientBaseTest : public GDBRemoteTest {};
+
+TEST_F(GDBRemoteClientBaseTest, SendContinueAndWait) {
+ StringExtractorGDBRemote response;
+ ContinueFixture fix;
+ if (HasFailure())
+ return;
+
+ // Continue. The inferior will stop with a signal.
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
+ ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
+ ASSERT_EQ("T01", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+
+ // Continue. The inferior will exit.
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("W01"));
+ ASSERT_EQ(eStateExited, fix.SendCPacket(response));
+ ASSERT_EQ("W01", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+
+ // Continue. The inferior will get killed.
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("X01"));
+ ASSERT_EQ(eStateExited, fix.SendCPacket(response));
+ ASSERT_EQ("X01", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
}
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncSignal)
-{
- StringExtractorGDBRemote continue_response, response;
- ContinueFixture fix;
- if (HasFailure())
- return;
-
- // SendAsyncSignal should do nothing when we are not running.
- ASSERT_FALSE(fix.client.SendAsyncSignal(0x47));
-
- // Continue. After the run packet is sent, send an async signal.
- std::future<StateType> continue_state =
- std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- fix.WaitForRunEvent();
-
- std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.SendAsyncSignal(0x47); });
-
- // First we'll get interrupted.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
-
- // Then we get the signal packet.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("C47", response.GetStringRef());
- ASSERT_TRUE(async_result.get());
-
- // And we report back a signal stop.
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T47"));
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T47", continue_response.GetStringRef());
+TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncSignal) {
+ StringExtractorGDBRemote continue_response, response;
+ ContinueFixture fix;
+ if (HasFailure())
+ return;
+
+ // SendAsyncSignal should do nothing when we are not running.
+ ASSERT_FALSE(fix.client.SendAsyncSignal(0x47));
+
+ // Continue. After the run packet is sent, send an async signal.
+ std::future<StateType> continue_state = std::async(
+ std::launch::async, [&] { return fix.SendCPacket(continue_response); });
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+ fix.WaitForRunEvent();
+
+ std::future<bool> async_result = std::async(
+ std::launch::async, [&] { return fix.client.SendAsyncSignal(0x47); });
+
+ // First we'll get interrupted.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
+
+ // Then we get the signal packet.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("C47", response.GetStringRef());
+ ASSERT_TRUE(async_result.get());
+
+ // And we report back a signal stop.
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T47"));
+ ASSERT_EQ(eStateStopped, continue_state.get());
+ ASSERT_EQ("T47", continue_response.GetStringRef());
}
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncPacket)
-{
- StringExtractorGDBRemote continue_response, async_response, response;
- const bool send_async = true;
- ContinueFixture fix;
- if (HasFailure())
- return;
-
- // Continue. After the run packet is sent, send an async packet.
- std::future<StateType> continue_state =
- std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- fix.WaitForRunEvent();
-
- // Sending without async enabled should fail.
- ASSERT_EQ(PacketResult::ErrorSendFailed, fix.client.SendPacketAndWaitForResponse("qTest1", response, !send_async));
-
- std::future<PacketResult> async_result = std::async(std::launch::async, [&] {
- return fix.client.SendPacketAndWaitForResponse("qTest2", async_response, send_async);
- });
-
- // First we'll get interrupted.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
-
- // Then we get the async packet.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("qTest2", response.GetStringRef());
-
- // Send the response and receive it.
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest2"));
- ASSERT_EQ(PacketResult::Success, async_result.get());
- ASSERT_EQ("QTest2", async_response.GetStringRef());
-
- // And we get resumed again.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T01", continue_response.GetStringRef());
+TEST_F(GDBRemoteClientBaseTest, SendContinueAndAsyncPacket) {
+ StringExtractorGDBRemote continue_response, async_response, response;
+ const bool send_async = true;
+ ContinueFixture fix;
+ if (HasFailure())
+ return;
+
+ // Continue. After the run packet is sent, send an async packet.
+ std::future<StateType> continue_state = std::async(
+ std::launch::async, [&] { return fix.SendCPacket(continue_response); });
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+ fix.WaitForRunEvent();
+
+ // Sending without async enabled should fail.
+ ASSERT_EQ(
+ PacketResult::ErrorSendFailed,
+ fix.client.SendPacketAndWaitForResponse("qTest1", response, !send_async));
+
+ std::future<PacketResult> async_result = std::async(std::launch::async, [&] {
+ return fix.client.SendPacketAndWaitForResponse("qTest2", async_response,
+ send_async);
+ });
+
+ // First we'll get interrupted.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
+
+ // Then we get the async packet.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("qTest2", response.GetStringRef());
+
+ // Send the response and receive it.
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest2"));
+ ASSERT_EQ(PacketResult::Success, async_result.get());
+ ASSERT_EQ("QTest2", async_response.GetStringRef());
+
+ // And we get resumed again.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
+ ASSERT_EQ(eStateStopped, continue_state.get());
+ ASSERT_EQ("T01", continue_response.GetStringRef());
}
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt)
-{
- StringExtractorGDBRemote continue_response, response;
- ContinueFixture fix;
- if (HasFailure())
- return;
-
- // Interrupt should do nothing when we're not running.
- ASSERT_FALSE(fix.client.Interrupt());
-
- // Continue. After the run packet is sent, send an interrupt.
- std::future<StateType> continue_state =
- std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- fix.WaitForRunEvent();
-
- std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
-
- // We get interrupted.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
-
- // And that's it.
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T13", continue_response.GetStringRef());
- ASSERT_TRUE(async_result.get());
+TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt) {
+ StringExtractorGDBRemote continue_response, response;
+ ContinueFixture fix;
+ if (HasFailure())
+ return;
+
+ // Interrupt should do nothing when we're not running.
+ ASSERT_FALSE(fix.client.Interrupt());
+
+ // Continue. After the run packet is sent, send an interrupt.
+ std::future<StateType> continue_state = std::async(
+ std::launch::async, [&] { return fix.SendCPacket(continue_response); });
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+ fix.WaitForRunEvent();
+
+ std::future<bool> async_result =
+ std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
+
+ // We get interrupted.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
+
+ // And that's it.
+ ASSERT_EQ(eStateStopped, continue_state.get());
+ ASSERT_EQ("T13", continue_response.GetStringRef());
+ ASSERT_TRUE(async_result.get());
}
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndLateInterrupt)
-{
- StringExtractorGDBRemote continue_response, response;
- ContinueFixture fix;
- if (HasFailure())
- return;
-
- // Continue. After the run packet is sent, send an interrupt.
- std::future<StateType> continue_state =
- std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- fix.WaitForRunEvent();
-
- std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
-
- // However, the target stops due to a different reason than the original interrupt.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T01", continue_response.GetStringRef());
- ASSERT_TRUE(async_result.get());
-
- // The subsequent continue packet should work normally.
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
+TEST_F(GDBRemoteClientBaseTest, SendContinueAndLateInterrupt) {
+ StringExtractorGDBRemote continue_response, response;
+ ContinueFixture fix;
+ if (HasFailure())
+ return;
+
+ // Continue. After the run packet is sent, send an interrupt.
+ std::future<StateType> continue_state = std::async(
+ std::launch::async, [&] { return fix.SendCPacket(continue_response); });
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+ fix.WaitForRunEvent();
+
+ std::future<bool> async_result =
+ std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
+
+ // However, the target stops due to a different reason than the original
+ // interrupt.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
+ ASSERT_EQ(eStateStopped, continue_state.get());
+ ASSERT_EQ("T01", continue_response.GetStringRef());
+ ASSERT_TRUE(async_result.get());
+
+ // The subsequent continue packet should work normally.
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
+ ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
+ ASSERT_EQ("T01", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
}
-TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug)
-{
- StringExtractorGDBRemote continue_response, async_response, response;
- const bool send_async = true;
- ContinueFixture fix;
- if (HasFailure())
- return;
-
- // Interrupt should do nothing when we're not running.
- ASSERT_FALSE(fix.client.Interrupt());
-
- // Continue. After the run packet is sent, send an async signal.
- std::future<StateType> continue_state =
- std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- fix.WaitForRunEvent();
-
- std::future<bool> interrupt_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
-
- // We get interrupted. We'll send two packets to simulate a buggy stub.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
-
- // We should stop.
- ASSERT_EQ(eStateStopped, continue_state.get());
- ASSERT_EQ("T13", continue_response.GetStringRef());
- ASSERT_TRUE(interrupt_result.get());
-
- // Packet stream should remain synchronized.
- std::future<PacketResult> send_result = std::async(std::launch::async, [&] {
- return fix.client.SendPacketAndWaitForResponse("qTest", async_response, !send_async);
- });
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("qTest", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest"));
- ASSERT_EQ(PacketResult::Success, send_result.get());
- ASSERT_EQ("QTest", async_response.GetStringRef());
+TEST_F(GDBRemoteClientBaseTest, SendContinueAndInterrupt2PacketBug) {
+ StringExtractorGDBRemote continue_response, async_response, response;
+ const bool send_async = true;
+ ContinueFixture fix;
+ if (HasFailure())
+ return;
+
+ // Interrupt should do nothing when we're not running.
+ ASSERT_FALSE(fix.client.Interrupt());
+
+ // Continue. After the run packet is sent, send an async signal.
+ std::future<StateType> continue_state = std::async(
+ std::launch::async, [&] { return fix.SendCPacket(continue_response); });
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+ fix.WaitForRunEvent();
+
+ std::future<bool> interrupt_result =
+ std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
+
+ // We get interrupted. We'll send two packets to simulate a buggy stub.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("\x03", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T13"));
+
+ // We should stop.
+ ASSERT_EQ(eStateStopped, continue_state.get());
+ ASSERT_EQ("T13", continue_response.GetStringRef());
+ ASSERT_TRUE(interrupt_result.get());
+
+ // Packet stream should remain synchronized.
+ std::future<PacketResult> send_result = std::async(std::launch::async, [&] {
+ return fix.client.SendPacketAndWaitForResponse("qTest", async_response,
+ !send_async);
+ });
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("qTest", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("QTest"));
+ ASSERT_EQ(PacketResult::Success, send_result.get());
+ ASSERT_EQ("QTest", async_response.GetStringRef());
}
-TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateInterface)
-{
- StringExtractorGDBRemote response;
- ContinueFixture fix;
- if (HasFailure())
- return;
-
- // Continue. We'll have the server send a bunch of async packets before it stops.
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4142"));
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Apro"));
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4344"));
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Afile"));
- ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
- ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
- ASSERT_EQ("T01", response.GetStringRef());
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
-
- EXPECT_EQ("ABCD", fix.delegate.output);
- EXPECT_EQ("profile", fix.delegate.misc_data);
- EXPECT_EQ(1u, fix.delegate.stop_reply_called);
+TEST_F(GDBRemoteClientBaseTest, SendContinueDelegateInterface) {
+ StringExtractorGDBRemote response;
+ ContinueFixture fix;
+ if (HasFailure())
+ return;
+
+ // Continue. We'll have the server send a bunch of async packets before it
+ // stops.
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4142"));
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Apro"));
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("O4344"));
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("Afile"));
+ ASSERT_EQ(PacketResult::Success, fix.server.SendPacket("T01"));
+ ASSERT_EQ(eStateStopped, fix.SendCPacket(response));
+ ASSERT_EQ("T01", response.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+
+ EXPECT_EQ("ABCD", fix.delegate.output);
+ EXPECT_EQ("profile", fix.delegate.misc_data);
+ EXPECT_EQ(1u, fix.delegate.stop_reply_called);
}
-TEST_F(GDBRemoteClientBaseTest, InterruptNoResponse)
-{
- StringExtractorGDBRemote continue_response, response;
- ContinueFixture fix;
- if (HasFailure())
- return;
-
- // Continue. After the run packet is sent, send an interrupt.
- std::future<StateType> continue_state =
- std::async(std::launch::async, [&] { return fix.SendCPacket(continue_response); });
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("c", response.GetStringRef());
- fix.WaitForRunEvent();
-
- std::future<bool> async_result = std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
-
- // We get interrupted, but we don't send a stop packet.
- ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
- ASSERT_EQ("\x03", response.GetStringRef());
-
- // The functions should still terminate (after a timeout).
- ASSERT_TRUE(async_result.get());
- ASSERT_EQ(eStateInvalid, continue_state.get());
+TEST_F(GDBRemoteClientBaseTest, InterruptNoResponse) {
+ StringExtractorGDBRemote continue_response, response;
+ ContinueFixture fix;
+ if (HasFailure())
+ return;
+
+ // Continue. After the run packet is sent, send an interrupt.
+ std::future<StateType> continue_state = std::async(
+ std::launch::async, [&] { return fix.SendCPacket(continue_response); });
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("c", response.GetStringRef());
+ fix.WaitForRunEvent();
+
+ std::future<bool> async_result =
+ std::async(std::launch::async, [&] { return fix.client.Interrupt(); });
+
+ // We get interrupted, but we don't send a stop packet.
+ ASSERT_EQ(PacketResult::Success, fix.server.GetPacket(response));
+ ASSERT_EQ("\x03", response.GetStringRef());
+
+ // The functions should still terminate (after a timeout).
+ ASSERT_TRUE(async_result.get());
+ ASSERT_EQ(eStateInvalid, continue_state.get());
}
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
index 0b1f60d..d74ac66 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp
@@ -8,7 +8,8 @@
//===----------------------------------------------------------------------===//
#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread> when
+// Workaround for MSVC standard library bug, which fails to include <thread>
+// when
// exceptions are disabled.
#include <eh.h>
#endif
@@ -26,159 +27,162 @@ using namespace lldb_private::process_gdb_remote;
using namespace lldb_private;
using namespace lldb;
-namespace
-{
+namespace {
typedef GDBRemoteCommunication::PacketResult PacketResult;
-struct TestClient : public GDBRemoteCommunicationClient
-{
- TestClient() { m_send_acks = false; }
+struct TestClient : public GDBRemoteCommunicationClient {
+ TestClient() { m_send_acks = false; }
};
-void
-Handle_QThreadSuffixSupported(MockServer &server, bool supported)
-{
- StringExtractorGDBRemote request;
- ASSERT_EQ(PacketResult::Success, server.GetPacket(request));
- ASSERT_EQ("QThreadSuffixSupported", request.GetStringRef());
- if (supported)
- ASSERT_EQ(PacketResult::Success, server.SendOKResponse());
- else
- ASSERT_EQ(PacketResult::Success, server.SendUnimplementedResponse(nullptr));
+void Handle_QThreadSuffixSupported(MockServer &server, bool supported) {
+ StringExtractorGDBRemote request;
+ ASSERT_EQ(PacketResult::Success, server.GetPacket(request));
+ ASSERT_EQ("QThreadSuffixSupported", request.GetStringRef());
+ if (supported)
+ ASSERT_EQ(PacketResult::Success, server.SendOKResponse());
+ else
+ ASSERT_EQ(PacketResult::Success, server.SendUnimplementedResponse(nullptr));
}
-void
-HandlePacket(MockServer &server, llvm::StringRef expected, llvm::StringRef response)
-{
- StringExtractorGDBRemote request;
- ASSERT_EQ(PacketResult::Success, server.GetPacket(request));
- ASSERT_EQ(expected, request.GetStringRef());
- ASSERT_EQ(PacketResult::Success, server.SendPacket(response));
+void HandlePacket(MockServer &server, llvm::StringRef expected,
+ llvm::StringRef response) {
+ StringExtractorGDBRemote request;
+ ASSERT_EQ(PacketResult::Success, server.GetPacket(request));
+ ASSERT_EQ(expected, request.GetStringRef());
+ ASSERT_EQ(PacketResult::Success, server.SendPacket(response));
}
-uint8_t all_registers[] = {'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'};
+uint8_t all_registers[] = {'@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+ 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'};
std::string all_registers_hex = "404142434445464748494a4b4c4d4e4f";
uint8_t one_register[] = {'A', 'B', 'C', 'D'};
std::string one_register_hex = "41424344";
} // end anonymous namespace
-class GDBRemoteCommunicationClientTest : public GDBRemoteTest
-{
-};
+class GDBRemoteCommunicationClientTest : public GDBRemoteTest {};
-TEST_F(GDBRemoteCommunicationClientTest, WriteRegister)
-{
- TestClient client;
- MockServer server;
- Connect(client, server);
- if (HasFailure())
- return;
+TEST_F(GDBRemoteCommunicationClientTest, WriteRegister) {
+ TestClient client;
+ MockServer server;
+ Connect(client, server);
+ if (HasFailure())
+ return;
- const lldb::tid_t tid = 0x47;
- const uint32_t reg_num = 4;
- std::future<bool> write_result =
- std::async(std::launch::async, [&] { return client.WriteRegister(tid, reg_num, one_register); });
+ const lldb::tid_t tid = 0x47;
+ const uint32_t reg_num = 4;
+ std::future<bool> write_result = std::async(std::launch::async, [&] {
+ return client.WriteRegister(tid, reg_num, one_register);
+ });
- Handle_QThreadSuffixSupported(server, true);
+ Handle_QThreadSuffixSupported(server, true);
- HandlePacket(server, "P4=" + one_register_hex + ";thread:0047;", "OK");
- ASSERT_TRUE(write_result.get());
+ HandlePacket(server, "P4=" + one_register_hex + ";thread:0047;", "OK");
+ ASSERT_TRUE(write_result.get());
- write_result = std::async(std::launch::async, [&] { return client.WriteAllRegisters(tid, all_registers); });
+ write_result = std::async(std::launch::async, [&] {
+ return client.WriteAllRegisters(tid, all_registers);
+ });
- HandlePacket(server, "G" + all_registers_hex + ";thread:0047;", "OK");
- ASSERT_TRUE(write_result.get());
+ HandlePacket(server, "G" + all_registers_hex + ";thread:0047;", "OK");
+ ASSERT_TRUE(write_result.get());
}
-TEST_F(GDBRemoteCommunicationClientTest, WriteRegisterNoSuffix)
-{
- TestClient client;
- MockServer server;
- Connect(client, server);
- if (HasFailure())
- return;
-
- const lldb::tid_t tid = 0x47;
- const uint32_t reg_num = 4;
- std::future<bool> write_result =
- std::async(std::launch::async, [&] { return client.WriteRegister(tid, reg_num, one_register); });
-
- Handle_QThreadSuffixSupported(server, false);
- HandlePacket(server, "Hg47", "OK");
- HandlePacket(server, "P4=" + one_register_hex, "OK");
- ASSERT_TRUE(write_result.get());
-
- write_result = std::async(std::launch::async, [&] { return client.WriteAllRegisters(tid, all_registers); });
-
- HandlePacket(server, "G" + all_registers_hex, "OK");
- ASSERT_TRUE(write_result.get());
+TEST_F(GDBRemoteCommunicationClientTest, WriteRegisterNoSuffix) {
+ TestClient client;
+ MockServer server;
+ Connect(client, server);
+ if (HasFailure())
+ return;
+
+ const lldb::tid_t tid = 0x47;
+ const uint32_t reg_num = 4;
+ std::future<bool> write_result = std::async(std::launch::async, [&] {
+ return client.WriteRegister(tid, reg_num, one_register);
+ });
+
+ Handle_QThreadSuffixSupported(server, false);
+ HandlePacket(server, "Hg47", "OK");
+ HandlePacket(server, "P4=" + one_register_hex, "OK");
+ ASSERT_TRUE(write_result.get());
+
+ write_result = std::async(std::launch::async, [&] {
+ return client.WriteAllRegisters(tid, all_registers);
+ });
+
+ HandlePacket(server, "G" + all_registers_hex, "OK");
+ ASSERT_TRUE(write_result.get());
}
-TEST_F(GDBRemoteCommunicationClientTest, ReadRegister)
-{
- TestClient client;
- MockServer server;
- Connect(client, server);
- if (HasFailure())
- return;
-
- const lldb::tid_t tid = 0x47;
- const uint32_t reg_num = 4;
- std::future<bool> async_result = std::async(std::launch::async, [&] { return client.GetpPacketSupported(tid); });
- Handle_QThreadSuffixSupported(server, true);
- HandlePacket(server, "p0;thread:0047;", one_register_hex);
- ASSERT_TRUE(async_result.get());
-
- std::future<DataBufferSP> read_result =
- std::async(std::launch::async, [&] { return client.ReadRegister(tid, reg_num); });
- HandlePacket(server, "p4;thread:0047;", "41424344");
- auto buffer_sp = read_result.get();
- ASSERT_TRUE(bool(buffer_sp));
- ASSERT_EQ(0, memcmp(buffer_sp->GetBytes(), one_register, sizeof one_register));
-
- read_result = std::async(std::launch::async, [&] { return client.ReadAllRegisters(tid); });
- HandlePacket(server, "g;thread:0047;", all_registers_hex);
- buffer_sp = read_result.get();
- ASSERT_TRUE(bool(buffer_sp));
- ASSERT_EQ(0, memcmp(buffer_sp->GetBytes(), all_registers, sizeof all_registers));
+TEST_F(GDBRemoteCommunicationClientTest, ReadRegister) {
+ TestClient client;
+ MockServer server;
+ Connect(client, server);
+ if (HasFailure())
+ return;
+
+ const lldb::tid_t tid = 0x47;
+ const uint32_t reg_num = 4;
+ std::future<bool> async_result = std::async(
+ std::launch::async, [&] { return client.GetpPacketSupported(tid); });
+ Handle_QThreadSuffixSupported(server, true);
+ HandlePacket(server, "p0;thread:0047;", one_register_hex);
+ ASSERT_TRUE(async_result.get());
+
+ std::future<DataBufferSP> read_result = std::async(
+ std::launch::async, [&] { return client.ReadRegister(tid, reg_num); });
+ HandlePacket(server, "p4;thread:0047;", "41424344");
+ auto buffer_sp = read_result.get();
+ ASSERT_TRUE(bool(buffer_sp));
+ ASSERT_EQ(0,
+ memcmp(buffer_sp->GetBytes(), one_register, sizeof one_register));
+
+ read_result = std::async(std::launch::async,
+ [&] { return client.ReadAllRegisters(tid); });
+ HandlePacket(server, "g;thread:0047;", all_registers_hex);
+ buffer_sp = read_result.get();
+ ASSERT_TRUE(bool(buffer_sp));
+ ASSERT_EQ(0,
+ memcmp(buffer_sp->GetBytes(), all_registers, sizeof all_registers));
}
-TEST_F(GDBRemoteCommunicationClientTest, SaveRestoreRegistersNoSuffix)
-{
- TestClient client;
- MockServer server;
- Connect(client, server);
- if (HasFailure())
- return;
-
- const lldb::tid_t tid = 0x47;
- uint32_t save_id;
- std::future<bool> async_result =
- std::async(std::launch::async, [&] { return client.SaveRegisterState(tid, save_id); });
- Handle_QThreadSuffixSupported(server, false);
- HandlePacket(server, "Hg47", "OK");
- HandlePacket(server, "QSaveRegisterState", "1");
- ASSERT_TRUE(async_result.get());
- EXPECT_EQ(1u, save_id);
-
- async_result = std::async(std::launch::async, [&] { return client.RestoreRegisterState(tid, save_id); });
- HandlePacket(server, "QRestoreRegisterState:1", "OK");
- ASSERT_TRUE(async_result.get());
+TEST_F(GDBRemoteCommunicationClientTest, SaveRestoreRegistersNoSuffix) {
+ TestClient client;
+ MockServer server;
+ Connect(client, server);
+ if (HasFailure())
+ return;
+
+ const lldb::tid_t tid = 0x47;
+ uint32_t save_id;
+ std::future<bool> async_result = std::async(std::launch::async, [&] {
+ return client.SaveRegisterState(tid, save_id);
+ });
+ Handle_QThreadSuffixSupported(server, false);
+ HandlePacket(server, "Hg47", "OK");
+ HandlePacket(server, "QSaveRegisterState", "1");
+ ASSERT_TRUE(async_result.get());
+ EXPECT_EQ(1u, save_id);
+
+ async_result = std::async(std::launch::async, [&] {
+ return client.RestoreRegisterState(tid, save_id);
+ });
+ HandlePacket(server, "QRestoreRegisterState:1", "OK");
+ ASSERT_TRUE(async_result.get());
}
-TEST_F(GDBRemoteCommunicationClientTest, SyncThreadState)
-{
- TestClient client;
- MockServer server;
- Connect(client, server);
- if (HasFailure())
- return;
-
- const lldb::tid_t tid = 0x47;
- std::future<bool> async_result = std::async(std::launch::async, [&] { return client.SyncThreadState(tid); });
- HandlePacket(server, "qSyncThreadStateSupported", "OK");
- HandlePacket(server, "QSyncThreadState:0047;", "OK");
- ASSERT_TRUE(async_result.get());
+TEST_F(GDBRemoteCommunicationClientTest, SyncThreadState) {
+ TestClient client;
+ MockServer server;
+ Connect(client, server);
+ if (HasFailure())
+ return;
+
+ const lldb::tid_t tid = 0x47;
+ std::future<bool> async_result = std::async(
+ std::launch::async, [&] { return client.SyncThreadState(tid); });
+ HandlePacket(server, "qSyncThreadStateSupported", "OK");
+ HandlePacket(server, "QSyncThreadState:0047;", "OK");
+ ASSERT_TRUE(async_result.get());
}
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
index 3aee52e..58cc9f5 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.cpp
@@ -8,7 +8,8 @@
//===----------------------------------------------------------------------===//
#if defined(_MSC_VER) && (_HAS_EXCEPTIONS == 0)
-// Workaround for MSVC standard library bug, which fails to include <thread> when
+// Workaround for MSVC standard library bug, which fails to include <thread>
+// when
// exceptions are disabled.
#include <eh.h>
#endif
@@ -20,53 +21,48 @@
#include <future>
-namespace lldb_private
-{
-namespace process_gdb_remote
-{
+namespace lldb_private {
+namespace process_gdb_remote {
-void
-GDBRemoteTest::SetUpTestCase()
-{
+void GDBRemoteTest::SetUpTestCase() {
#if defined(_MSC_VER)
- WSADATA data;
- ::WSAStartup(MAKEWORD(2, 2), &data);
+ WSADATA data;
+ ::WSAStartup(MAKEWORD(2, 2), &data);
#endif
}
-void
-GDBRemoteTest::TearDownTestCase()
-{
+void GDBRemoteTest::TearDownTestCase() {
#if defined(_MSC_VER)
- ::WSACleanup();
+ ::WSACleanup();
#endif
}
-void
-Connect(GDBRemoteCommunication &client, GDBRemoteCommunication &server)
-{
- bool child_processes_inherit = false;
- Error error;
- TCPSocket listen_socket(child_processes_inherit, error);
- ASSERT_FALSE(error.Fail());
- error = listen_socket.Listen("127.0.0.1:0", 5);
- ASSERT_FALSE(error.Fail());
+void Connect(GDBRemoteCommunication &client, GDBRemoteCommunication &server) {
+ bool child_processes_inherit = false;
+ Error error;
+ TCPSocket listen_socket(child_processes_inherit, error);
+ ASSERT_FALSE(error.Fail());
+ error = listen_socket.Listen("127.0.0.1:0", 5);
+ ASSERT_FALSE(error.Fail());
- Socket *accept_socket;
- std::future<Error> accept_error = std::async(std::launch::async, [&] {
- return listen_socket.Accept("127.0.0.1:0", child_processes_inherit, accept_socket);
- });
+ Socket *accept_socket;
+ std::future<Error> accept_error = std::async(std::launch::async, [&] {
+ return listen_socket.Accept("127.0.0.1:0", child_processes_inherit,
+ accept_socket);
+ });
- char connect_remote_address[64];
- snprintf(connect_remote_address, sizeof(connect_remote_address), "connect://localhost:%u",
- listen_socket.GetLocalPortNumber());
+ char connect_remote_address[64];
+ snprintf(connect_remote_address, sizeof(connect_remote_address),
+ "connect://localhost:%u", listen_socket.GetLocalPortNumber());
- std::unique_ptr<ConnectionFileDescriptor> conn_ap(new ConnectionFileDescriptor());
- ASSERT_EQ(conn_ap->Connect(connect_remote_address, nullptr), lldb::eConnectionStatusSuccess);
+ std::unique_ptr<ConnectionFileDescriptor> conn_ap(
+ new ConnectionFileDescriptor());
+ ASSERT_EQ(conn_ap->Connect(connect_remote_address, nullptr),
+ lldb::eConnectionStatusSuccess);
- client.SetConnection(conn_ap.release());
- ASSERT_TRUE(accept_error.get().Success());
- server.SetConnection(new ConnectionFileDescriptor(accept_socket));
+ client.SetConnection(conn_ap.release());
+ ASSERT_TRUE(accept_error.get().Success());
+ server.SetConnection(new ConnectionFileDescriptor(accept_socket));
}
} // namespace process_gdb_remote
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h b/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h
index 6ceeccf..2aad2ae 100644
--- a/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h
+++ b/lldb/unittests/Process/gdb-remote/GDBRemoteTestUtils.h
@@ -9,47 +9,40 @@
#ifndef lldb_unittests_Process_gdb_remote_GDBRemoteTestUtils_h
#define lldb_unittests_Process_gdb_remote_GDBRemoteTestUtils_h
-#include "gtest/gtest.h"
#include "Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h"
+#include "gtest/gtest.h"
-namespace lldb_private
-{
-namespace process_gdb_remote
-{
+namespace lldb_private {
+namespace process_gdb_remote {
-class GDBRemoteTest : public testing::Test
-{
+class GDBRemoteTest : public testing::Test {
public:
- static void
- SetUpTestCase();
+ static void SetUpTestCase();
- static void
- TearDownTestCase();
+ static void TearDownTestCase();
};
-void
-Connect(GDBRemoteCommunication &client, GDBRemoteCommunication &server);
-
-struct MockServer : public GDBRemoteCommunicationServer
-{
- MockServer() : GDBRemoteCommunicationServer("mock-server", "mock-server.listener") { m_send_acks = false; }
-
- PacketResult
- SendPacket(llvm::StringRef payload)
- {
- return GDBRemoteCommunicationServer::SendPacketNoLock(payload);
- }
-
- PacketResult
- GetPacket(StringExtractorGDBRemote &response)
- {
- const unsigned timeout_usec = 1000000; // 1s
- const bool sync_on_timeout = false;
- return WaitForPacketWithTimeoutMicroSecondsNoLock(response, timeout_usec, sync_on_timeout);
- }
-
- using GDBRemoteCommunicationServer::SendOKResponse;
- using GDBRemoteCommunicationServer::SendUnimplementedResponse;
+void Connect(GDBRemoteCommunication &client, GDBRemoteCommunication &server);
+
+struct MockServer : public GDBRemoteCommunicationServer {
+ MockServer()
+ : GDBRemoteCommunicationServer("mock-server", "mock-server.listener") {
+ m_send_acks = false;
+ }
+
+ PacketResult SendPacket(llvm::StringRef payload) {
+ return GDBRemoteCommunicationServer::SendPacketNoLock(payload);
+ }
+
+ PacketResult GetPacket(StringExtractorGDBRemote &response) {
+ const unsigned timeout_usec = 1000000; // 1s
+ const bool sync_on_timeout = false;
+ return WaitForPacketWithTimeoutMicroSecondsNoLock(response, timeout_usec,
+ sync_on_timeout);
+ }
+
+ using GDBRemoteCommunicationServer::SendOKResponse;
+ using GDBRemoteCommunicationServer::SendUnimplementedResponse;
};
} // namespace process_gdb_remote