diff options
author | Walter Erquinigo <a20012251@gmail.com> | 2020-11-09 13:36:26 -0800 |
---|---|---|
committer | Walter Erquinigo <a20012251@gmail.com> | 2021-03-30 17:31:37 -0700 |
commit | 0b69756110db444282c40ea16929186b2910c3b1 (patch) | |
tree | 328177fba14ef2d43aa597e6274f536d4c44caed /lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp | |
parent | c23ee7718ea4f9292622af3d80efe2491eb2a506 (diff) | |
download | llvm-0b69756110db444282c40ea16929186b2910c3b1.zip llvm-0b69756110db444282c40ea16929186b2910c3b1.tar.gz llvm-0b69756110db444282c40ea16929186b2910c3b1.tar.bz2 |
[trace][intel-pt] Implement trace start and trace stop
This implements the interactive trace start and stop methods.
This diff ended up being much larger than I anticipated because, by doing it, I found that I had implemented in the beginning many things in a non optimal way. In any case, the code is much better now.
There's a lot of boilerplate code due to the gdb-remote protocol, but the main changes are:
- New tracing packets: jLLDBTraceStop, jLLDBTraceStart, jLLDBTraceGetBinaryData. The gdb-remote packet definitions are quite comprehensive.
- Implementation of the "process trace start|stop" and "thread trace start|stop" commands.
- Implementaiton of an API in Trace.h to interact with live traces.
- Created an IntelPTDecoder for live threads, that use the debugger's stop id as checkpoint for its internal cache.
- Added a functionality to stop the process in case "process tracing" is enabled and a new thread can't traced.
- Added tests
I have some ideas to unify the code paths for post mortem and live threads, but I'll do that in another diff.
Differential Revision: https://reviews.llvm.org/D91679
Diffstat (limited to 'lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp')
-rw-r--r-- | lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp | 209 |
1 files changed, 9 insertions, 200 deletions
diff --git a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp index 2cca197..0a9a42a 100644 --- a/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp +++ b/lldb/unittests/Process/gdb-remote/GDBRemoteCommunicationClientTest.cpp @@ -381,12 +381,12 @@ TEST_F(GDBRemoteCommunicationClientTest, GetMemoryRegionInfoInvalidResponse) { EXPECT_FALSE(result.get().Success()); } -TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedTypePacket) { - TraceTypeInfo trace_type; +TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedPacket) { + TraceSupportedResponse trace_type; std::string error_message; auto callback = [&] { - if (llvm::Expected<TraceTypeInfo> trace_type_or_err = - client.SendGetSupportedTraceType()) { + if (llvm::Expected<TraceSupportedResponse> trace_type_or_err = + client.SendTraceSupported()) { trace_type = *trace_type_or_err; error_message = ""; return true; @@ -402,7 +402,7 @@ TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedTypePacket) { std::future<bool> result = std::async(std::launch::async, callback); HandlePacket( - server, "jLLDBTraceSupportedType", + server, "jLLDBTraceSupported", R"({"name":"intel-pt","description":"Intel Processor Trace"}])"); EXPECT_TRUE(result.get()); @@ -414,17 +414,17 @@ TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedTypePacket) { { std::future<bool> result = std::async(std::launch::async, callback); - HandlePacket(server, "jLLDBTraceSupportedType", R"({"type":"intel-pt"}])"); + HandlePacket(server, "jLLDBTraceSupported", R"({"type":"intel-pt"}])"); EXPECT_FALSE(result.get()); - ASSERT_STREQ(error_message.c_str(), "missing value at (root).name"); + ASSERT_STREQ(error_message.c_str(), "missing value at (root).description"); } // Error response { std::future<bool> result = std::async(std::launch::async, callback); - HandlePacket(server, "jLLDBTraceSupportedType", "E23"); + HandlePacket(server, "jLLDBTraceSupported", "E23"); EXPECT_FALSE(result.get()); } @@ -433,7 +433,7 @@ TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedTypePacket) { { std::future<bool> result = std::async(std::launch::async, callback); - HandlePacket(server, "jLLDBTraceSupportedType", + HandlePacket(server, "jLLDBTraceSupported", "E23;50726F63657373206E6F742072756E6E696E672E"); EXPECT_FALSE(result.get()); @@ -441,197 +441,6 @@ TEST_F(GDBRemoteCommunicationClientTest, SendTraceSupportedTypePacket) { } } -TEST_F(GDBRemoteCommunicationClientTest, SendStartTracePacket) { - TraceOptions options; - Status error; - - options.setType(lldb::TraceType::eTraceTypeProcessorTrace); - options.setMetaDataBufferSize(8192); - options.setTraceBufferSize(8192); - options.setThreadID(0x23); - - StructuredData::DictionarySP custom_params = - std::make_shared<StructuredData::Dictionary>(); - custom_params->AddStringItem("tracetech", "intel-pt"); - custom_params->AddIntegerItem("psb", 0x01); - - options.setTraceParams(custom_params); - - std::future<lldb::user_id_t> result = std::async(std::launch::async, [&] { - return client.SendStartTracePacket(options, error); - }); - - // Since the line is exceeding 80 characters. - std::string expected_packet1 = - R"(jTraceStart:{"buffersize":8192,"metabuffersize":8192,"params":)"; - std::string expected_packet2 = - R"({"psb":1,"tracetech":"intel-pt"},"threadid":35,"type":1})"; - HandlePacket(server, (expected_packet1 + expected_packet2), "1"); - ASSERT_TRUE(error.Success()); - ASSERT_EQ(result.get(), 1u); - - error.Clear(); - result = std::async(std::launch::async, [&] { - return client.SendStartTracePacket(options, error); - }); - - HandlePacket(server, (expected_packet1 + expected_packet2), "E23"); - ASSERT_EQ(result.get(), LLDB_INVALID_UID); - ASSERT_FALSE(error.Success()); -} - -TEST_F(GDBRemoteCommunicationClientTest, SendStopTracePacket) { - lldb::tid_t thread_id = 0x23; - lldb::user_id_t trace_id = 3; - - std::future<Status> result = std::async(std::launch::async, [&] { - return client.SendStopTracePacket(trace_id, thread_id); - }); - - const char *expected_packet = R"(jTraceStop:{"threadid":35,"traceid":3})"; - HandlePacket(server, expected_packet, "OK"); - ASSERT_TRUE(result.get().Success()); - - result = std::async(std::launch::async, [&] { - return client.SendStopTracePacket(trace_id, thread_id); - }); - - HandlePacket(server, expected_packet, "E23"); - ASSERT_FALSE(result.get().Success()); -} - -TEST_F(GDBRemoteCommunicationClientTest, SendGetDataPacket) { - lldb::tid_t thread_id = 0x23; - lldb::user_id_t trace_id = 3; - - uint8_t buf[32] = {}; - llvm::MutableArrayRef<uint8_t> buffer(buf, 32); - size_t offset = 0; - - std::future<Status> result = std::async(std::launch::async, [&] { - return client.SendGetDataPacket(trace_id, thread_id, buffer, offset); - }); - - std::string expected_packet1 = - R"(jTraceBufferRead:{"buffersize":32,"offset":0,"threadid":35,)"; - std::string expected_packet2 = R"("traceid":3})"; - HandlePacket(server, expected_packet1+expected_packet2, "123456"); - ASSERT_TRUE(result.get().Success()); - ASSERT_EQ(buffer.size(), 3u); - ASSERT_EQ(buf[0], 0x12); - ASSERT_EQ(buf[1], 0x34); - ASSERT_EQ(buf[2], 0x56); - - llvm::MutableArrayRef<uint8_t> buffer2(buf, 32); - result = std::async(std::launch::async, [&] { - return client.SendGetDataPacket(trace_id, thread_id, buffer2, offset); - }); - - HandlePacket(server, expected_packet1+expected_packet2, "E23"); - ASSERT_FALSE(result.get().Success()); - ASSERT_EQ(buffer2.size(), 0u); -} - -TEST_F(GDBRemoteCommunicationClientTest, SendGetMetaDataPacket) { - lldb::tid_t thread_id = 0x23; - lldb::user_id_t trace_id = 3; - - uint8_t buf[32] = {}; - llvm::MutableArrayRef<uint8_t> buffer(buf, 32); - size_t offset = 0; - - std::future<Status> result = std::async(std::launch::async, [&] { - return client.SendGetMetaDataPacket(trace_id, thread_id, buffer, offset); - }); - - std::string expected_packet1 = - R"(jTraceMetaRead:{"buffersize":32,"offset":0,"threadid":35,)"; - std::string expected_packet2 = R"("traceid":3})"; - HandlePacket(server, expected_packet1+expected_packet2, "123456"); - ASSERT_TRUE(result.get().Success()); - ASSERT_EQ(buffer.size(), 3u); - ASSERT_EQ(buf[0], 0x12); - ASSERT_EQ(buf[1], 0x34); - ASSERT_EQ(buf[2], 0x56); - - llvm::MutableArrayRef<uint8_t> buffer2(buf, 32); - result = std::async(std::launch::async, [&] { - return client.SendGetMetaDataPacket(trace_id, thread_id, buffer2, offset); - }); - - HandlePacket(server, expected_packet1+expected_packet2, "E23"); - ASSERT_FALSE(result.get().Success()); - ASSERT_EQ(buffer2.size(), 0u); -} - -TEST_F(GDBRemoteCommunicationClientTest, SendGetTraceConfigPacket) { - lldb::tid_t thread_id = 0x23; - lldb::user_id_t trace_id = 3; - TraceOptions options; - options.setThreadID(thread_id); - - std::future<Status> result = std::async(std::launch::async, [&] { - return client.SendGetTraceConfigPacket(trace_id, options); - }); - - const char *expected_packet = - R"(jTraceConfigRead:{"threadid":35,"traceid":3})"; - std::string response1 = - R"({"buffersize":8192,"params":{"psb":1,"tracetech":"intel-pt"})"; - std::string response2 = R"(],"metabuffersize":8192,"threadid":35,"type":1}])"; - HandlePacket(server, expected_packet, response1+response2); - ASSERT_TRUE(result.get().Success()); - ASSERT_EQ(options.getTraceBufferSize(), 8192u); - ASSERT_EQ(options.getMetaDataBufferSize(), 8192u); - ASSERT_EQ(options.getType(), 1); - - auto custom_params = options.getTraceParams(); - - uint64_t psb_value; - llvm::StringRef trace_tech_value; - - ASSERT_TRUE(custom_params); - ASSERT_EQ(custom_params->GetType(), eStructuredDataTypeDictionary); - ASSERT_TRUE(custom_params->GetValueForKeyAsInteger("psb", psb_value)); - ASSERT_EQ(psb_value, 1u); - ASSERT_TRUE( - custom_params->GetValueForKeyAsString("tracetech", trace_tech_value)); - ASSERT_STREQ(trace_tech_value.data(), "intel-pt"); - - // Checking error response. - std::future<Status> result2 = std::async(std::launch::async, [&] { - return client.SendGetTraceConfigPacket(trace_id, options); - }); - - HandlePacket(server, expected_packet, "E23"); - ASSERT_FALSE(result2.get().Success()); - - // Wrong JSON as response. - std::future<Status> result3 = std::async(std::launch::async, [&] { - return client.SendGetTraceConfigPacket(trace_id, options); - }); - - std::string incorrect_json1 = - R"("buffersize" : 8192,"params" : {"psb" : 1,"tracetech" : "intel-pt"})"; - std::string incorrect_json2 = - R"(],"metabuffersize" : 8192,"threadid" : 35,"type" : 1}])"; - HandlePacket(server, expected_packet, incorrect_json1+incorrect_json2); - ASSERT_FALSE(result3.get().Success()); - - // Wrong JSON as custom_params. - std::future<Status> result4 = std::async(std::launch::async, [&] { - return client.SendGetTraceConfigPacket(trace_id, options); - }); - - std::string incorrect_custom_params1 = - R"({"buffersize" : 8192,"params" : "psb" : 1,"tracetech" : "intel-pt"})"; - std::string incorrect_custom_params2 = - R"(],"metabuffersize" : 8192,"threadid" : 35,"type" : 1}])"; - HandlePacket(server, expected_packet, incorrect_custom_params1+ - incorrect_custom_params2); - ASSERT_FALSE(result4.get().Success()); -} - TEST_F(GDBRemoteCommunicationClientTest, GetQOffsets) { const auto &GetQOffsets = [&](llvm::StringRef response) { std::future<Optional<QOffsets>> result = std::async( |