From c7193b52fb5584535a211cbf305429fcfd6159e5 Mon Sep 17 00:00:00 2001 From: Ryan Houdek Date: Fri, 10 Nov 2023 12:17:23 -0800 Subject: [PATCH] GdbServer: Switch over to a unix domain socket Resolving the issue that we can only ever have one gdbserver process running consuming port 8086 (even if the port number is cute). Doesn't give us anything yet but in the future will allow us to have whole process trees running gdbservers that we can attach to. --- .../FEXLoader/LinuxSyscalls/GdbServer.cpp | 50 ++++++++++--------- .../Tools/FEXLoader/LinuxSyscalls/GdbServer.h | 1 + 2 files changed, 27 insertions(+), 24 deletions(-) diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/GdbServer.cpp b/Source/Tools/FEXLoader/LinuxSyscalls/GdbServer.cpp index 625a373db..fa0cf8611 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/GdbServer.cpp +++ b/Source/Tools/FEXLoader/LinuxSyscalls/GdbServer.cpp @@ -12,6 +12,7 @@ $end_info$ #include #include +#include #include #include #include @@ -32,6 +33,7 @@ $end_info$ #include #include #include +#include #include #include @@ -47,6 +49,7 @@ $end_info$ #include #include #include +#include #include #include @@ -1275,6 +1278,7 @@ void GdbServer::GdbServerLoop() { } close(ListenSocket); + unlink(GdbUnixSocketPath.c_str()); } static void* ThreadHandler(void *Arg) { auto This = reinterpret_cast(Arg); @@ -1289,38 +1293,37 @@ void GdbServer::StartThread() { } void GdbServer::OpenListenSocket() { - // getaddrinfo allocates memory that can't be removed. - FEXCore::Allocator::YesIKnowImNotSupposedToUseTheGlibcAllocator glibc; - struct addrinfo hints, *res; - - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_PASSIVE; - - if(getaddrinfo(NULL, "8086", &hints, &res) < 0) { - perror("getaddrinfo"); + const auto GdbUnixPath = fextl::fmt::format("{}/FEX_gdbserver/", FEXServerClient::GetServerMountFolder()); + if (FHU::Filesystem::CreateDirectory(GdbUnixPath) == FHU::Filesystem::CreateDirectoryResult::ERROR) { + LogMan::Msg::EFmt("[GdbServer] Couldn't create gdbserver folder {}", GdbUnixPath); + return; } - int on = 1; + GdbUnixSocketPath = fextl::fmt::format("{}{}-gdb", GdbUnixPath, ::getpid()); - ListenSocket = socket(res->ai_family, res->ai_socktype, res->ai_protocol); - if (ListenSocket < 0) { - perror("socket"); + ListenSocket = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (ListenSocket == -1) { + LogMan::Msg::EFmt("[GdbServer] Couldn't open AF_UNIX socket {} {}", errno, strerror(errno)); + return; } - if(setsockopt(ListenSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof(on)) < 0) { - perror("setsockopt"); - close(ListenSocket); - } - if (bind(ListenSocket, res->ai_addr, res->ai_addrlen) < 0) { - perror("bind"); + struct sockaddr_un addr{}; + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, GdbUnixSocketPath.data(), sizeof(addr.sun_path)); + size_t SizeOfAddr = offsetof(sockaddr_un, sun_path) + GdbUnixSocketPath.size(); + + // Bind the socket to the path + int Result = bind(ListenSocket, reinterpret_cast(&addr), SizeOfAddr); + if (Result == -1) { + LogMan::Msg::EFmt("[GdbServer] Couldn't bind AF_UNIX socket '{}': {} {}\n", addr.sun_path, errno, strerror(errno)); close(ListenSocket); + ListenSocket = -1; + return; } listen(ListenSocket, 1); - - freeaddrinfo(res); + LogMan::Msg::IFmt("[GdbServer] Waiting for connection on {}", GdbUnixSocketPath); + LogMan::Msg::IFmt("[GdbServer] gdb-multiarch -ex \"target extended-remote {}\"", GdbUnixSocketPath); } fextl::unique_ptr GdbServer::OpenSocket() { @@ -1328,7 +1331,6 @@ fextl::unique_ptr GdbServer::OpenSocket() { struct sockaddr_storage their_addr{}; socklen_t addr_size{}; - LogMan::Msg::IFmt("GdbServer, waiting for connection on localhost:8086"); int new_fd = accept(ListenSocket, (struct sockaddr *)&their_addr, &addr_size); return fextl::make_unique(new_fd); diff --git a/Source/Tools/FEXLoader/LinuxSyscalls/GdbServer.h b/Source/Tools/FEXLoader/LinuxSyscalls/GdbServer.h index 921048d30..9232c7278 100644 --- a/Source/Tools/FEXLoader/LinuxSyscalls/GdbServer.h +++ b/Source/Tools/FEXLoader/LinuxSyscalls/GdbServer.h @@ -93,6 +93,7 @@ private: std::array PassSignals{}; uint32_t CurrentDebuggingThread{}; int ListenSocket{}; + fextl::string GdbUnixSocketPath{}; FEX_CONFIG_OPT(Filename, APP_FILENAME); FEX_CONFIG_OPT(Is64BitMode, IS64BIT_MODE); };