Skip to content

Commit

Permalink
[lldb] Multithreading lldb-server works on Windows now; fixed gdb por…
Browse files Browse the repository at this point in the history
…t mapping

Removed fork(). Used threads and the common thread-safe port map for all platform connections.

Updated lldb::FileSystem to use llvm::vfs::createPhysicalFileSystem() with an own virtual working directory per thread.

This patch depends on llvm#100659, llvm#100666.

This patch fixes llvm#97537, llvm#90923, llvm#56346.

lldb-server has been tested on Windows with 50 connections and 100 processes launched simultaneously. Tested also the cross build with Linux x86_64 host and Linux Aarch64 target.
  • Loading branch information
slydiman committed Aug 1, 2024
1 parent 2d36550 commit 7fb5b2e
Show file tree
Hide file tree
Showing 7 changed files with 298 additions and 183 deletions.
7 changes: 7 additions & 0 deletions lldb/include/lldb/Host/FileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,12 @@ class FileSystem {

static FileSystem &Instance();

static void InitializePerThread() {
lldbassert(!InstancePerThread() && "Already initialized.");
InstancePerThread().emplace(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>(
llvm::vfs::createPhysicalFileSystem().release()));
}

template <class... T> static void Initialize(T &&...t) {
lldbassert(!InstanceImpl() && "Already initialized.");
InstanceImpl().emplace(std::forward<T>(t)...);
Expand Down Expand Up @@ -206,6 +212,7 @@ class FileSystem {

private:
static std::optional<FileSystem> &InstanceImpl();
static std::optional<FileSystem> &InstancePerThread();
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs;
std::unique_ptr<TildeExpressionResolver> m_tilde_resolver;
std::string m_home_directory;
Expand Down
8 changes: 8 additions & 0 deletions lldb/source/Host/common/FileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,15 @@ void FileSystem::Terminate() {
InstanceImpl().reset();
}

std::optional<FileSystem> &FileSystem::InstancePerThread() {
static thread_local std::optional<FileSystem> t_fs;
return t_fs;
}

std::optional<FileSystem> &FileSystem::InstanceImpl() {
std::optional<FileSystem> &fs = InstancePerThread();
if (fs)
return fs;
static std::optional<FileSystem> g_fs;
return g_fs;
}
Expand Down
12 changes: 12 additions & 0 deletions lldb/source/Host/posix/PipePosix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,18 @@ Status PipePosix::ReadWithTimeout(void *buf, size_t size,
bytes_read += result;
if (bytes_read == size || result == 0)
break;

// This is the workaround for the following bug in Linux multithreading
// select() https://bugzilla.kernel.org/show_bug.cgi?id=546
// ReadWithTimeout() with a non-zero timeout is used only to
// read the port number from the gdbserver pipe
// in GDBRemoteCommunication::StartDebugserverProcess().
// The port number may be "1024\0".."65535\0".
if (timeout.count() > 0 && size == 6 && bytes_read == 5 &&
static_cast<char *>(buf)[4] == '\0') {
break;
}

} else if (errno == EINTR) {
continue;
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,9 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Size(
packet.GetHexByteString(path);
if (!path.empty()) {
uint64_t Size;
if (llvm::sys::fs::file_size(path, Size))
FileSpec file_spec(path);
FileSystem::Instance().Resolve(file_spec);
if (llvm::sys::fs::file_size(file_spec.GetPath(), Size))
return SendErrorResponse(5);
StreamString response;
response.PutChar('F');
Expand Down Expand Up @@ -725,7 +727,9 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(
packet.SetFilePos(::strlen("vFile:unlink:"));
std::string path;
packet.GetHexByteString(path);
Status error(llvm::sys::fs::remove(path));
FileSpec file_spec(path);
FileSystem::Instance().Resolve(file_spec);
Status error(llvm::sys::fs::remove(file_spec.GetPath()));
StreamString response;
response.Printf("F%x,%x", error.GetError(), error.GetError());
return SendPacketNoLock(response.GetString());
Expand All @@ -744,6 +748,13 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
// uint32_t timeout = packet.GetHexMaxU32(false, 32);
if (packet.GetChar() == ',')
packet.GetHexByteString(working_dir);
else {
auto cwd = FileSystem::Instance()
.GetVirtualFileSystem()
->getCurrentWorkingDirectory();
if (cwd)
working_dir = *cwd;
}
int status, signo;
std::string output;
FileSpec working_spec(working_dir);
Expand Down
Loading

0 comments on commit 7fb5b2e

Please sign in to comment.