Skip to content

Commit 4f72abd

Browse files
[LLDB] Add support for the structured data plugins in lldb-server (#159457)
The LLDB client has support for structured data plugins, but lldb-server doesn't have corresponding support for it. This patch adds the missing functionality in LLGS for servers to register their supported plugins and send corresponding async messages.
1 parent 31e43e2 commit 4f72abd

File tree

6 files changed

+61
-0
lines changed

6 files changed

+61
-0
lines changed

lldb/include/lldb/Host/common/NativeProcessProtocol.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,14 @@ class NativeProcessProtocol {
409409
"Not implemented");
410410
}
411411

412+
/// Get the list of structured data plugins supported by this process. They
413+
/// must match the `type` field used by the corresponding
414+
/// StructuredDataPlugins in the client.
415+
///
416+
/// \return
417+
/// A vector of structured data plugin names.
418+
virtual std::vector<std::string> GetStructuredDataPlugins() { return {}; };
419+
412420
protected:
413421
struct SoftwareBreakpoint {
414422
uint32_t ref_count;

lldb/include/lldb/Utility/StringExtractorGDBRemote.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class StringExtractorGDBRemote : public StringExtractor {
119119
eServerPacketType_qRegisterInfo,
120120
eServerPacketType_qShlibInfoAddr,
121121
eServerPacketType_qStepPacketSupported,
122+
eServerPacketType_qStructuredDataPlugins,
122123
eServerPacketType_qSupported,
123124
eServerPacketType_qSyncThreadStateSupported,
124125
eServerPacketType_qThreadExtraInfo,

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ void GDBRemoteCommunicationServerLLGS::RegisterPacketHandlers() {
146146
RegisterMemberFunctionHandler(
147147
StringExtractorGDBRemote::eServerPacketType_QSetWorkingDir,
148148
&GDBRemoteCommunicationServerLLGS::Handle_QSetWorkingDir);
149+
RegisterMemberFunctionHandler(
150+
StringExtractorGDBRemote::eServerPacketType_qStructuredDataPlugins,
151+
&GDBRemoteCommunicationServerLLGS::Handle_qStructuredDataPlugins);
149152
RegisterMemberFunctionHandler(
150153
StringExtractorGDBRemote::eServerPacketType_qsThreadInfo,
151154
&GDBRemoteCommunicationServerLLGS::Handle_qsThreadInfo);
@@ -1245,6 +1248,19 @@ Status GDBRemoteCommunicationServerLLGS::InitializeConnection(
12451248
return error;
12461249
}
12471250

1251+
GDBRemoteCommunication::PacketResult
1252+
GDBRemoteCommunicationServerLLGS::SendStructuredDataPacket(
1253+
const llvm::json::Value &value) {
1254+
std::string json_string;
1255+
raw_string_ostream os(json_string);
1256+
os << value;
1257+
1258+
StreamGDBRemote escaped_response;
1259+
escaped_response.PutCString("JSON-async:");
1260+
escaped_response.PutEscapedBytes(json_string.c_str(), json_string.size());
1261+
return SendPacketNoLock(escaped_response.GetString());
1262+
}
1263+
12481264
GDBRemoteCommunication::PacketResult
12491265
GDBRemoteCommunicationServerLLGS::SendONotification(const char *buffer,
12501266
uint32_t len) {
@@ -1436,6 +1452,21 @@ GDBRemoteCommunicationServerLLGS::Handle_jLLDBTraceGetBinaryData(
14361452
return SendErrorResponse(bytes.takeError());
14371453
}
14381454

1455+
GDBRemoteCommunication::PacketResult
1456+
GDBRemoteCommunicationServerLLGS::Handle_qStructuredDataPlugins(
1457+
StringExtractorGDBRemote &packet) {
1458+
// Fail if we don't have a current process.
1459+
if (!m_current_process ||
1460+
(m_current_process->GetID() == LLDB_INVALID_PROCESS_ID))
1461+
return SendErrorResponse(68);
1462+
1463+
std::vector<std::string> structured_data_plugins =
1464+
m_current_process->GetStructuredDataPlugins();
1465+
1466+
return SendJSONResponse(
1467+
llvm::json::Value(llvm::json::Array(structured_data_plugins)));
1468+
}
1469+
14391470
GDBRemoteCommunication::PacketResult
14401471
GDBRemoteCommunicationServerLLGS::Handle_qProcessInfo(
14411472
StringExtractorGDBRemote &packet) {

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ class GDBRemoteCommunicationServerLLGS
8686

8787
Status InitializeConnection(std::unique_ptr<Connection> connection);
8888

89+
GDBRemoteCommunication::PacketResult
90+
SendStructuredDataPacket(const llvm::json::Value &value);
91+
8992
struct DebuggedProcess {
9093
enum class Flag {
9194
vkilled = (1u << 0),
@@ -185,6 +188,8 @@ class GDBRemoteCommunicationServerLLGS
185188

186189
PacketResult Handle_qsThreadInfo(StringExtractorGDBRemote &packet);
187190

191+
PacketResult Handle_qStructuredDataPlugins(StringExtractorGDBRemote &packet);
192+
188193
PacketResult Handle_p(StringExtractorGDBRemote &packet);
189194

190195
PacketResult Handle_P(StringExtractorGDBRemote &packet);

lldb/source/Utility/StringExtractorGDBRemote.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,8 @@ StringExtractorGDBRemote::GetServerPacketType() const {
280280
return eServerPacketType_qSupported;
281281
if (PACKET_MATCHES("qSyncThreadStateSupported"))
282282
return eServerPacketType_qSyncThreadStateSupported;
283+
if (PACKET_MATCHES("qStructuredDataPlugins"))
284+
return eServerPacketType_qStructuredDataPlugins;
283285
break;
284286

285287
case 'T':

lldb/unittests/tools/lldb-server/tests/LLGSTest.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include "TestBase.h"
1010
#include "lldb/Host/Host.h"
1111
#include "llvm/Testing/Support/Error.h"
12+
#include "gtest/gtest.h"
1213

1314
using namespace llgs_tests;
1415
using namespace lldb_private;
@@ -74,3 +75,16 @@ TEST_F(TestBase, LLGS_TEST(vAttachRichError)) {
7475
testing::StartsWith(
7576
"cannot attach to process 1 when another process with pid"))));
7677
}
78+
79+
TEST_F(TestBase, LLGS_TEST(qStructuredDataPlugins)) {
80+
auto ClientOr = TestClient::launchCustom(
81+
getLogFileName(),
82+
/* disable_stdio */ true, {}, {getInferiorPath("environment_check")});
83+
ASSERT_THAT_EXPECTED(ClientOr, Succeeded());
84+
auto &Client = **ClientOr;
85+
std::string response_string;
86+
ASSERT_THAT_ERROR(
87+
Client.SendMessage("qStructuredDataPlugins", response_string),
88+
Succeeded());
89+
EXPECT_STREQ("[]", response_string.c_str());
90+
}

0 commit comments

Comments
 (0)