Skip to content

Commit 0870140

Browse files
committed
[lldb] Multithreading lldb-server works on Windows now; fixed gdb port 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.
1 parent b1f263e commit 0870140

File tree

8 files changed

+300
-183
lines changed

8 files changed

+300
-183
lines changed

lldb/include/lldb/Host/FileSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ class FileSystem {
4747

4848
static FileSystem &Instance();
4949

50+
static void InitializePerThread() {
51+
lldbassert(!InstancePerThread() && "Already initialized.");
52+
InstancePerThread().emplace(llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>(
53+
llvm::vfs::createPhysicalFileSystem().release()));
54+
}
55+
5056
template <class... T> static void Initialize(T &&...t) {
5157
lldbassert(!InstanceImpl() && "Already initialized.");
5258
InstanceImpl().emplace(std::forward<T>(t)...);
@@ -206,6 +212,7 @@ class FileSystem {
206212

207213
private:
208214
static std::optional<FileSystem> &InstanceImpl();
215+
static std::optional<FileSystem> &InstancePerThread();
209216
llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> m_fs;
210217
std::unique_ptr<TildeExpressionResolver> m_tilde_resolver;
211218
std::string m_home_directory;

lldb/source/Host/common/FileSystem.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,15 @@ void FileSystem::Terminate() {
4949
InstanceImpl().reset();
5050
}
5151

52+
std::optional<FileSystem> &FileSystem::InstancePerThread() {
53+
static thread_local std::optional<FileSystem> t_fs;
54+
return t_fs;
55+
}
56+
5257
std::optional<FileSystem> &FileSystem::InstanceImpl() {
58+
std::optional<FileSystem> &fs = InstancePerThread();
59+
if (fs)
60+
return fs;
5361
static std::optional<FileSystem> g_fs;
5462
return g_fs;
5563
}

lldb/source/Host/posix/PipePosix.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,18 @@ Status PipePosix::ReadWithTimeout(void *buf, size_t size,
324324
bytes_read += result;
325325
if (bytes_read == size || result == 0)
326326
break;
327+
328+
// This is the workaround for the following bug in Linux multithreading
329+
// select() https://bugzilla.kernel.org/show_bug.cgi?id=546
330+
// ReadWithTimeout() with a non-zero timeout is used only to
331+
// read the port number from the gdbserver pipe
332+
// in GDBRemoteCommunication::StartDebugserverProcess().
333+
// The port number may be "1024\0".."65535\0".
334+
if (timeout.count() > 0 && size == 6 && bytes_read == 5 &&
335+
static_cast<char *>(buf)[4] == '\0') {
336+
break;
337+
}
338+
327339
} else if (errno == EINTR) {
328340
continue;
329341
} else {

lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -646,7 +646,9 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_Size(
646646
packet.GetHexByteString(path);
647647
if (!path.empty()) {
648648
uint64_t Size;
649-
if (llvm::sys::fs::file_size(path, Size))
649+
FileSpec file_spec(path);
650+
FileSystem::Instance().Resolve(file_spec);
651+
if (llvm::sys::fs::file_size(file_spec.GetPath(), Size))
650652
return SendErrorResponse(5);
651653
StreamString response;
652654
response.PutChar('F');
@@ -725,7 +727,9 @@ GDBRemoteCommunicationServerCommon::Handle_vFile_unlink(
725727
packet.SetFilePos(::strlen("vFile:unlink:"));
726728
std::string path;
727729
packet.GetHexByteString(path);
728-
Status error(llvm::sys::fs::remove(path));
730+
FileSpec file_spec(path);
731+
FileSystem::Instance().Resolve(file_spec);
732+
Status error(llvm::sys::fs::remove(file_spec.GetPath()));
729733
StreamString response;
730734
response.Printf("F%x,%x", error.GetError(), error.GetError());
731735
return SendPacketNoLock(response.GetString());
@@ -744,6 +748,13 @@ GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell(
744748
// uint32_t timeout = packet.GetHexMaxU32(false, 32);
745749
if (packet.GetChar() == ',')
746750
packet.GetHexByteString(working_dir);
751+
else {
752+
auto cwd = FileSystem::Instance()
753+
.GetVirtualFileSystem()
754+
->getCurrentWorkingDirectory();
755+
if (cwd)
756+
working_dir = *cwd;
757+
}
747758
int status, signo;
748759
std::string output;
749760
FileSpec working_spec(working_dir);

0 commit comments

Comments
 (0)