21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/JSON.h"
23#include "llvm/Support/Threading.h"
25#include "lldb/Host/Config.h"
50 for (; min_port < max_port; ++min_port)
60llvm::Expected<uint16_t>
72 return llvm::createStringError(llvm::inconvertibleErrorCode(),
73 "No free port found in port map");
87 std::map<uint16_t, lldb::pid_t>::iterator pos =
m_port_map.find(
port);
99 if (pair.second ==
pid) {
151 bool &interrupt,
bool &quit) {
152 error.SetErrorString(
"interrupt received");
164 std::optional<uint16_t> &port, std::string &socket_name) {
168 port = *available_port;
170 return Status(available_port.takeError());
181 if (hostname.empty())
182 hostname =
"127.0.0.1";
185 LLDB_LOGF(log,
"Launching debugserver with: %s:%u...", hostname.c_str(),
193 this, std::placeholders::_1));
195 std::ostringstream url;
197#if !defined(__APPLE__)
200 uint16_t *port_ptr = &*
port;
203 std::optional<URI> parsed_uri =
URI::Parse(platform_uri);
204 url <<
'[' << parsed_uri->hostname.str() <<
"]:" << *
port;
212 url.str().c_str(),
nullptr, debugserver_launch_info, port_ptr, &args, -1);
234 LLDB_LOGF(log,
"GDBRemoteCommunicationServerPlatform::%s() called",
238 std::string hostname;
239 packet.
SetFilePos(::strlen(
"qLaunchGDBServer;"));
240 llvm::StringRef name;
241 llvm::StringRef value;
242 std::optional<uint16_t>
port;
245 hostname = std::string(value);
246 else if (name ==
"port") {
249 value.getAsInteger(0, *
port);
259 "GDBRemoteCommunicationServerPlatform::%s() debugserver "
261 __FUNCTION__,
error.AsCString());
266 "GDBRemoteCommunicationServerPlatform::%s() debugserver "
267 "launched successfully as pid %" PRIu64,
268 __FUNCTION__, debugserver_pid);
272 response.
Printf(
"pid:%" PRIu64
";port:%u;", debugserver_pid,
285 return packet_result;
301 json::Array server_list;
302 server_list.push_back(std::move(server));
316 packet.
SetFilePos(::strlen(
"qKillSpawnedProcess:"));
348 for (
size_t i = 0; i < 10; ++i) {
356 std::this_thread::sleep_for(std::chrono::milliseconds(10));
369 for (
size_t i = 0; i < 10; ++i) {
377 std::this_thread::sleep_for(std::chrono::milliseconds(10));
412 packet.
SetFilePos(::strlen(
"qPathComplete:"));
413 const bool only_dir = (packet.
GetHexMaxU32(
false, 0) == 1);
428 llvm::StringRef separator;
429 std::sort(matches.
begin(), matches.
end());
430 for (
const auto &match : matches) {
431 response << separator;
445 llvm::SmallString<64> cwd;
446 if (std::error_code ec = llvm::sys::fs::current_path(cwd))
457 packet.
SetFilePos(::strlen(
"QSetWorkingDir:"));
461 if (std::error_code ec = llvm::sys::fs::set_current_path(path))
499 for (
auto signo = signals->GetFirstSignalNumber();
501 signo = signals->GetNextSignalNumber(signo)) {
502 auto dictionary = std::make_shared<StructuredData::Dictionary>();
504 dictionary->AddIntegerItem(
"signo", signo);
505 dictionary->AddStringItem(
"name", signals->GetSignalAsStringRef(signo));
507 bool suppress, stop, notify;
508 signals->GetSignalInfo(signo, suppress, stop, notify);
509 dictionary->AddBooleanItem(
"suppress", suppress);
510 dictionary->AddBooleanItem(
"stop", stop);
511 dictionary->AddBooleanItem(
"notify", notify);
513 signal_array.
Push(dictionary);
517 signal_array.
Dump(response);
530 return Status(
"%s: no process command line specified to launch",
538 std::placeholders::_1));
541 if (!
error.Success()) {
542 fprintf(stderr,
"%s: failed to launch executable %s", __FUNCTION__,
547 printf(
"Launched '%s' as process %" PRIu64
"...\n",
569 static llvm::once_flag g_once_flag;
571 llvm::call_once(g_once_flag, []() {
572 const char *domainsocket_dir_env =
573 ::getenv(
"LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
574 if (domainsocket_dir_env !=
nullptr)
575 g_domainsocket_dir =
FileSpec(domainsocket_dir_env);
577 g_domainsocket_dir = HostInfo::GetProcessTempDir();
580 return g_domainsocket_dir;
585 llvm::SmallString<128> socket_path;
587 (llvm::StringRef(prefix) +
".%%%%%%").str());
592 llvm::sys::fs::createUniqueFile(socket_path_spec.
GetPath().c_str(),
594 return FileSpec(socket_path.c_str());
602 lldb::pid_t pid, uint16_t port,
const std::string &socket_name) {
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOGF(log,...)
A command line argument class.
size_t GetArgumentCount() const
Gets the number of arguments left in this command object.
const char * GetArgumentAtIndex(size_t idx) const
Gets the NULL terminated C string argument pointer for the argument at index idx.
static void DiskDirectories(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher)
static void DiskFiles(CommandInterpreter &interpreter, CompletionRequest &request, SearchFilter *searcher)
lldb_private::Connection * GetConnection()
virtual std::string GetURI()=0
Returns a URI that describes this connection object.
void AppendPathComponent(llvm::StringRef component)
size_t GetPath(char *path, size_t max_path_length, bool denormalize=true) const
Extract the full path to the file.
static Status LaunchProcess(ProcessLaunchInfo &launch_info)
Launch the process specified in launch_info.
static bool GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &proc_info)
static void Kill(lldb::pid_t pid, int signo)
lldb::pid_t GetProcessID() const
const Host::MonitorChildProcessCallback & GetMonitorProcessCallback() const
void SetMonitorProcessCallback(Host::MonitorChildProcessCallback callback)
void SetLaunchInSeparateProcessGroup(bool separate)
int PutEscapedBytes(const void *s, size_t src_len)
Output a block of data to the stream performing GDB-remote escaping.
llvm::StringRef GetString() const
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
size_t PutStringAsRawHex8(llvm::StringRef s)
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
size_t PutBytesAsRawHex8(const void *src, size_t src_len, lldb::ByteOrder src_byte_order=lldb::eByteOrderInvalid, lldb::ByteOrder dst_byte_order=lldb::eByteOrderInvalid)
void Push(const ObjectSP &item)
void Dump(lldb_private::Stream &s, bool pretty_print=true) const
static lldb::UnixSignalsSP CreateForHost()
void RegisterMemberFunctionHandler(StringExtractorGDBRemote::ServerPacketType packet_type, PacketResult(T::*handler)(StringExtractorGDBRemote &packet))
static void CreateProcessInfoResponse_DebugServerStyle(const ProcessInstanceInfo &proc_info, StreamString &response)
ProcessLaunchInfo m_process_launch_info
void RegisterPacketHandler(StringExtractorGDBRemote::ServerPacketType packet_type, PacketHandler handler)
PacketResult SendErrorResponse(const Status &error)
PacketResult SendOKResponse()
Status StartDebugserverProcess(const char *url, Platform *platform, ProcessLaunchInfo &launch_info, uint16_t *port, const Args *inferior_args, int pass_comm_fd)
PacketResult SendPacketNoLock(llvm::StringRef payload)
#define LLDB_INVALID_SIGNAL_NUMBER
#define LLDB_INVALID_PROCESS_ID
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
std::shared_ptr< lldb_private::UnixSignals > UnixSignalsSP
static std::optional< URI > Parse(llvm::StringRef uri)