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;
77 if (connection.protocol == Socket::SocketProtocol::ProtocolUnixDomain)
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
135 CommandInterpreter &interpreter)
136 : CommandObjectMultiword(interpreter, "protocol-server",
137 "Start and stop a protocol server.",
138 "protocol-server") {
140 interpreter)));
142 new CommandObjectProtocolServerStop(interpreter)));
143}
144
static llvm::raw_ostream & error(Stream &strm)
~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
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)
static std::optional< ProtocolModePair > GetProtocolAndMode(llvm::StringRef scheme)
Definition: Socket.cpp:498
A class that represents a running process on the host machine.
Definition: SBAddress.h:15
std::shared_ptr< lldb_private::CommandObject > CommandObjectSP
Definition: lldb-forward.h:336
@ eReturnStatusSuccessFinishNoResult
@ eArgTypeProtocol
@ eArgTypeConnectURL
Definition: Debugger.h:58
static std::optional< URI > Parse(llvm::StringRef uri)
Definition: UriParser.cpp:28