LLDB mainline
CommandObjectProtocolServer.cpp
Go to the documentation of this file.
1//===-- CommandObjectProtocolServer.cpp -----------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
12#include "lldb/Host/Socket.h"
16#include "llvm/ADT/STLExtras.h"
17#include "llvm/Support/FormatAdapters.h"
18#include <string>
19
20using namespace llvm;
21using namespace lldb;
22using namespace lldb_private;
23
24#define LLDB_OPTIONS_mcp
25#include "CommandOptions.inc"
26
28public:
30 : CommandObjectParsed(interpreter, "protocol-server start",
31 "start protocol server",
32 "protocol-server start <protocol> [<connection>]") {
35 }
36
38
39protected:
40 void DoExecute(Args &args, CommandReturnObject &result) override {
41 if (args.GetArgumentCount() < 1) {
42 result.AppendError("no protocol specified");
43 return;
44 }
45
46 llvm::StringRef protocol = args.GetArgumentAtIndex(0);
48 if (!server) {
50 "unsupported protocol: {0}. Supported protocols are: {1}", protocol,
51 llvm::join(ProtocolServer::GetSupportedProtocols(), ", "));
52 return;
53 }
54
55 std::string connection_uri = "listen://[localhost]:0";
56 if (args.GetArgumentCount() >= 2)
57 connection_uri = args.GetArgumentAtIndex(1);
58
59 const char *connection_error =
60 "unsupported connection specifier, expected 'accept:///path' "
61 "or 'listen://[host]:port', got '{0}'.";
62 auto uri = lldb_private::URI::Parse(connection_uri);
63 if (!uri) {
64 result.AppendErrorWithFormatv(connection_error, connection_uri);
65 return;
66 }
67
68 std::optional<Socket::ProtocolModePair> protocol_and_mode =
69 Socket::GetProtocolAndMode(uri->scheme);
70 if (!protocol_and_mode || protocol_and_mode->second != Socket::ModeAccept) {
71 result.AppendErrorWithFormatv(connection_error, connection_uri);
72 return;
73 }
74
76 connection.protocol = protocol_and_mode->first;
78 connection.name = uri->path;
79 else
80 connection.name = formatv(
81 "[{0}]:{1}", uri->hostname.empty() ? "0.0.0.0" : uri->hostname,
82 uri->port.value_or(0));
83
84 if (llvm::Error error = server->Start(connection)) {
85 result.AppendErrorWithFormatv("{0}", llvm::fmt_consume(std::move(error)));
86 return;
87 }
88
89 if (Socket *socket = server->GetSocket()) {
90 std::string address =
91 llvm::join(socket->GetListeningConnectionURI(), ", ");
93 "{0} server started with connection listeners: {1}", protocol,
94 address);
96 }
97 }
98};
99
101public:
103 : CommandObjectParsed(interpreter, "protocol-server stop",
104 "stop protocol server",
105 "protocol-server stop <protocol>") {
107 }
108
110
111protected:
112 void DoExecute(Args &args, CommandReturnObject &result) override {
113 if (args.GetArgumentCount() < 1) {
114 result.AppendError("no protocol specified");
115 return;
116 }
117
118 llvm::StringRef protocol = args.GetArgumentAtIndex(0);
120 if (!server) {
122 "unsupported protocol: {0}. Supported protocols are: {1}", protocol,
123 llvm::join(ProtocolServer::GetSupportedProtocols(), ", "));
124 return;
125 }
126
127 if (llvm::Error error = server->Stop()) {
128 result.AppendErrorWithFormatv("{0}", llvm::fmt_consume(std::move(error)));
129 return;
130 }
131 }
132};
133
135public:
137 : CommandObjectParsed(interpreter, "protocol-server get",
138 "get protocol server connection information",
139 "protocol-server get <protocol>") {
141 }
142
144
145protected:
146 void DoExecute(Args &args, CommandReturnObject &result) override {
147 if (args.GetArgumentCount() < 1) {
148 result.AppendError("no protocol specified");
149 return;
150 }
151
152 llvm::StringRef protocol = args.GetArgumentAtIndex(0);
154 if (!server) {
156 "unsupported protocol: {0}. Supported protocols are: {1}", protocol,
157 llvm::join(ProtocolServer::GetSupportedProtocols(), ", "));
158 return;
159 }
160
161 Socket *socket = server->GetSocket();
162 if (!socket) {
163 result.AppendErrorWithFormatv("{0} server is not running", protocol);
164 return;
165 }
166
167 std::string address = llvm::join(socket->GetListeningConnectionURI(), ", ");
168 result.AppendMessageWithFormatv("{0} server connection listeners: {1}",
169 protocol, address);
171 }
172};
173
175 CommandInterpreter &interpreter)
176 : CommandObjectMultiword(interpreter, "protocol-server",
177 "Start, stop, and query protocol servers.",
178 "protocol-server") {
180 interpreter)));
182 new CommandObjectProtocolServerStop(interpreter)));
184 "get", CommandObjectSP(new CommandObjectProtocolServerGet(interpreter)));
185}
186
static llvm::raw_ostream & error(Stream &strm)
void DoExecute(Args &args, CommandReturnObject &result) override
CommandObjectProtocolServerGet(CommandInterpreter &interpreter)
~CommandObjectProtocolServerGet() override=default
~CommandObjectProtocolServerStart() override=default
CommandObjectProtocolServerStart(CommandInterpreter &interpreter)
void DoExecute(Args &args, CommandReturnObject &result) override
void DoExecute(Args &args, CommandReturnObject &result) override
~CommandObjectProtocolServerStop() override=default
CommandObjectProtocolServerStop(CommandInterpreter &interpreter)
A command line argument class.
Definition Args.h:33
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
Definition Args.h:120
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
Definition Args.cpp:273
bool LoadSubCommand(llvm::StringRef cmd_name, const lldb::CommandObjectSP &command_obj) override
CommandObjectMultiword(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectParsed(CommandInterpreter &interpreter, const char *name, const char *help=nullptr, const char *syntax=nullptr, uint32_t flags=0)
CommandObjectProtocolServer(CommandInterpreter &interpreter)
void AddSimpleArgumentList(lldb::CommandArgumentType arg_type, ArgumentRepetitionType repetition_type=eArgRepeatPlain)
void void AppendError(llvm::StringRef in_string)
void SetStatus(lldb::ReturnStatus status)
void void AppendMessageWithFormatv(const char *format, Args &&...args)
void AppendErrorWithFormatv(const char *format, Args &&...args)
virtual Socket * GetSocket() const =0
static std::vector< llvm::StringRef > GetSupportedProtocols()
virtual llvm::Error Stop()=0
virtual llvm::Error Start(Connection connection)=0
static ProtocolServer * GetOrCreate(llvm::StringRef name)
virtual std::vector< std::string > GetListeningConnectionURI() const
Definition Socket.h:169
static std::optional< ProtocolModePair > GetProtocolAndMode(llvm::StringRef scheme)
Definition Socket.cpp:498
A class that represents a running process on the host machine.
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
@ eReturnStatusSuccessFinishNoResult
static std::optional< URI > Parse(llvm::StringRef uri)
Definition UriParser.cpp:28