aboutsummaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
diff options
context:
space:
mode:
authorPavel Labath <pavel@labath.sk>2025-02-27 11:15:59 +0100
committerGitHub <noreply@github.com>2025-02-27 11:15:59 +0100
commitc0b5451129bba52e33cd7957d58af897a58d14c6 (patch)
tree65471124ea25a26bd5267ce79ceb0ef35d189fa9 /lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
parent0e3ba99ad65f7025d37c857f9b587b767f7709e7 (diff)
downloadllvm-c0b5451129bba52e33cd7957d58af897a58d14c6.zip
llvm-c0b5451129bba52e33cd7957d58af897a58d14c6.tar.gz
llvm-c0b5451129bba52e33cd7957d58af897a58d14c6.tar.bz2
[lldb] Assorted improvements to the Pipe class (#128719)
The main motivation for this was the inconsistency in handling of partial reads/writes between the windows and posix implementations (windows was returning partial reads, posix was trying to fill the buffer completely). I settle on the windows implementation, as that's the more common behavior, and the "eager" version can be implemented on top of that (in most cases, it isn't necessary, since we're writing just a single byte). Since this also required auditing the callers to make sure they're handling partial reads/writes correctly, I used the opportunity to modernize the function signatures as a forcing function. They now use the `Timeout` class (basically an `optional<duration>`) to support both polls (timeout=0) and blocking (timeout=nullopt) operations in a single function, and use an `Expected` instead of a by-ref result to return the number of bytes read/written. As a drive-by, I also fix a problem with the windows implementation where we were rounding the timeout value down, which meant that calls could time out slightly sooner than expected.
Diffstat (limited to 'lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp')
-rw-r--r--lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp24
1 files changed, 17 insertions, 7 deletions
diff --git a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
index f746ced..dad72a1 100644
--- a/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
+++ b/lldb/source/Plugins/Process/gdb-remote/GDBRemoteCommunication.cpp
@@ -30,7 +30,9 @@
#include "lldb/Utility/Log.h"
#include "lldb/Utility/RegularExpression.h"
#include "lldb/Utility/StreamString.h"
+#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallString.h"
+#include "llvm/ADT/StringRef.h"
#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_ZLIB
#include "llvm/Support/ScopedPrinter.h"
@@ -1154,17 +1156,25 @@ Status GDBRemoteCommunication::StartDebugserverProcess(
if (socket_pipe.CanWrite())
socket_pipe.CloseWriteFileDescriptor();
if (socket_pipe.CanRead()) {
- // The port number may be up to "65535\0".
- char port_cstr[6] = {0};
- size_t num_bytes = sizeof(port_cstr);
// Read port from pipe with 10 second timeout.
- error = socket_pipe.ReadWithTimeout(
- port_cstr, num_bytes, std::chrono::seconds{10}, num_bytes);
+ std::string port_str;
+ while (error.Success()) {
+ char buf[10];
+ if (llvm::Expected<size_t> num_bytes = socket_pipe.Read(
+ buf, std::size(buf), std::chrono::seconds(10))) {
+ if (*num_bytes == 0)
+ break;
+ port_str.append(buf, *num_bytes);
+ } else {
+ error = Status::FromError(num_bytes.takeError());
+ }
+ }
if (error.Success() && (port != nullptr)) {
- assert(num_bytes > 0 && port_cstr[num_bytes - 1] == '\0');
+ // NB: Deliberately using .c_str() to stop at embedded '\0's
+ llvm::StringRef port_ref = port_str.c_str();
uint16_t child_port = 0;
// FIXME: improve error handling
- llvm::to_integer(port_cstr, child_port);
+ llvm::to_integer(port_ref, child_port);
if (*port == 0 || *port == child_port) {
*port = child_port;
LLDB_LOGF(log,