21#include "llvm/Support/FileSystem.h"
22#include "llvm/Support/JSON.h"
23#include "llvm/Support/Threading.h"
25#include "lldb/Host/Config.h"
49 for (; min_port < max_port; ++min_port)
58llvm::Expected<uint16_t>
70 return llvm::createStringError(llvm::inconvertibleErrorCode(),
71 "No free port found in port map");
85 std::map<uint16_t, lldb::pid_t>::iterator pos =
m_port_map.find(
port);
97 if (pair.second ==
pid) {
149 bool &interrupt,
bool &quit) {
150 error.SetErrorString(
"interrupt received");
162 std::optional<uint16_t> &port, std::string &socket_name) {
166 port = *available_port;
168 return Status(available_port.takeError());
179 if (hostname.empty())
180 hostname =
"127.0.0.1";
183 LLDB_LOGF(log,
"Launching debugserver with: %s:%u...", hostname.c_str(),
191 this, std::placeholders::_1));
193 std::ostringstream url;
195#if !defined(__APPLE__)
201 std::optional<URI> parsed_uri =
URI::Parse(platform_uri);
202 url <<
'[' << parsed_uri->hostname.str() <<
"]:" << *
port;
210 url.str().c_str(),
nullptr, debugserver_launch_info, port_ptr, &args, -1);
232 LLDB_LOGF(log,
"GDBRemoteCommunicationServerPlatform::%s() called",
236 std::string hostname;
237 packet.
SetFilePos(::strlen(
"qLaunchGDBServer;"));
238 llvm::StringRef name;
239 llvm::StringRef value;
240 std::optional<uint16_t>
port;
242 if (name.equals(
"host"))
243 hostname = std::string(value);
244 else if (name.equals(
"port")) {
247 value.getAsInteger(0, *
port);
257 "GDBRemoteCommunicationServerPlatform::%s() debugserver "
259 __FUNCTION__,
error.AsCString());
264 "GDBRemoteCommunicationServerPlatform::%s() debugserver "
265 "launched successfully as pid %" PRIu64,
266 __FUNCTION__, debugserver_pid);
270 response.
Printf(
"pid:%" PRIu64
";port:%u;", debugserver_pid,
283 return packet_result;
299 json::Array server_list;
300 server_list.push_back(std::move(server));
314 packet.
SetFilePos(::strlen(
"qKillSpawnedProcess:"));
346 for (
size_t i = 0; i < 10; ++i) {
354 std::this_thread::sleep_for(std::chrono::milliseconds(10));
367 for (
size_t i = 0; i < 10; ++i) {
375 std::this_thread::sleep_for(std::chrono::milliseconds(10));
410 packet.
SetFilePos(::strlen(
"qPathComplete:"));
411 const bool only_dir = (packet.
GetHexMaxU32(
false, 0) == 1);
426 llvm::StringRef separator;
427 std::sort(matches.
begin(), matches.
end());
428 for (
const auto &match : matches) {
429 response << separator;
443 llvm::SmallString<64> cwd;
444 if (std::error_code ec = llvm::sys::fs::current_path(cwd))
455 packet.
SetFilePos(::strlen(
"QSetWorkingDir:"));
459 if (std::error_code ec = llvm::sys::fs::set_current_path(path))
497 for (
auto signo = signals->GetFirstSignalNumber();
499 signo = signals->GetNextSignalNumber(signo)) {
500 auto dictionary = std::make_shared<StructuredData::Dictionary>();
502 dictionary->AddIntegerItem(
"signo", signo);
503 dictionary->AddStringItem(
"name", signals->GetSignalAsCString(signo));
505 bool suppress, stop, notify;
506 signals->GetSignalInfo(signo, suppress, stop, notify);
507 dictionary->AddBooleanItem(
"suppress", suppress);
508 dictionary->AddBooleanItem(
"stop", stop);
509 dictionary->AddBooleanItem(
"notify", notify);
511 signal_array.
Push(dictionary);
515 signal_array.
Dump(response);
528 return Status(
"%s: no process command line specified to launch",
536 std::placeholders::_1));
539 if (!
error.Success()) {
540 fprintf(stderr,
"%s: failed to launch executable %s", __FUNCTION__,
545 printf(
"Launched '%s' as process %" PRIu64
"...\n",
567 static llvm::once_flag g_once_flag;
569 llvm::call_once(g_once_flag, []() {
570 const char *domainsocket_dir_env =
571 ::getenv(
"LLDB_DEBUGSERVER_DOMAINSOCKET_DIR");
572 if (domainsocket_dir_env !=
nullptr)
573 g_domainsocket_dir =
FileSpec(domainsocket_dir_env);
575 g_domainsocket_dir = HostInfo::GetProcessTempDir();
578 return g_domainsocket_dir;
583 llvm::SmallString<128> socket_path;
585 (llvm::StringRef(prefix) +
".%%%%%%").str());
590 llvm::sys::fs::createUniqueFile(socket_path_spec.
GetPath().c_str(),
592 return FileSpec(socket_path.c_str());
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.
static std::optional< URI > Parse(llvm::StringRef uri)