summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/Commands/CommandObjectThread.cpp6
-rw-r--r--source/Core/DumpDataExtractor.cpp3
-rw-r--r--source/Host/common/File.cpp74
-rw-r--r--source/Host/common/MainLoop.cpp27
-rw-r--r--source/Host/common/NativeProcessProtocol.cpp33
-rw-r--r--source/Host/common/SocketAddress.cpp2
-rw-r--r--source/Host/macosx/Host.mm6
-rw-r--r--source/Host/posix/ConnectionFileDescriptorPosix.cpp21
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp76
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h69
-rw-r--r--source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp4
-rw-r--r--source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp6
-rw-r--r--source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp5
-rw-r--r--source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp6
-rw-r--r--source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp3
-rw-r--r--source/Plugins/Language/ObjC/Cocoa.cpp12
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.cpp8
-rw-r--r--source/Plugins/Platform/Android/PlatformAndroid.h2
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.cpp8
-rw-r--r--source/Plugins/Platform/POSIX/PlatformPOSIX.h4
-rw-r--r--source/Plugins/Process/FreeBSD/ProcessMonitor.cpp24
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.cpp317
-rw-r--r--source/Plugins/Process/Linux/NativeProcessLinux.h37
-rw-r--r--source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp6
-rwxr-xr-xsource/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp21
-rw-r--r--source/Plugins/Process/Linux/ProcessorTrace.cpp37
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp265
-rw-r--r--source/Plugins/Process/NetBSD/NativeProcessNetBSD.h28
-rw-r--r--source/Plugins/Process/gdb-remote/CMakeLists.txt8
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp28
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h3
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp26
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h7
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp9
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp71
-rw-r--r--source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h15
-rw-r--r--source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp1
-rw-r--r--source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp14
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp20
-rw-r--r--source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h2
-rw-r--r--source/Utility/StringExtractorGDBRemote.cpp37
-rw-r--r--source/Utility/StringExtractorGDBRemote.h4
42 files changed, 590 insertions, 765 deletions
diff --git a/source/Commands/CommandObjectThread.cpp b/source/Commands/CommandObjectThread.cpp
index 687187b26ccd..6a933df43e14 100644
--- a/source/Commands/CommandObjectThread.cpp
+++ b/source/Commands/CommandObjectThread.cpp
@@ -161,9 +161,9 @@ public:
// List the common thread ID's
const std::vector<uint32_t> &thread_index_ids =
stack.GetUniqueThreadIndexIDs();
- strm.Printf("%lu thread(s) ", thread_index_ids.size());
+ strm.Format("{0} thread(s) ", thread_index_ids.size());
for (const uint32_t &thread_index_id : thread_index_ids) {
- strm.Printf("#%u ", thread_index_id);
+ strm.Format("#{0} ", thread_index_id);
}
strm.EOL();
@@ -209,7 +209,7 @@ protected:
Process *process = m_exe_ctx.GetProcessPtr();
Thread *thread = process->GetThreadList().FindThreadByID(tid).get();
if (thread == nullptr) {
- result.AppendErrorWithFormat("Failed to process thread# %llu.\n", tid);
+ result.AppendErrorWithFormatv("Failed to process thread #{0}.\n", tid);
result.SetStatus(eReturnStatusFailed);
return false;
}
diff --git a/source/Core/DumpDataExtractor.cpp b/source/Core/DumpDataExtractor.cpp
index 2b7abd60f8bc..c2a9115c3068 100644
--- a/source/Core/DumpDataExtractor.cpp
+++ b/source/Core/DumpDataExtractor.cpp
@@ -154,7 +154,8 @@ lldb::offset_t lldb_private::DumpDataExtractor(
target_sp = exe_scope->CalculateTarget();
if (target_sp) {
DisassemblerSP disassembler_sp(Disassembler::FindPlugin(
- target_sp->GetArchitecture(), nullptr, nullptr));
+ target_sp->GetArchitecture(),
+ target_sp->GetDisassemblyFlavor(), nullptr));
if (disassembler_sp) {
lldb::addr_t addr = base_addr + start_offset;
lldb_private::Address so_addr;
diff --git a/source/Host/common/File.cpp b/source/Host/common/File.cpp
index 3de93ebc220b..90a4462c6ca9 100644
--- a/source/Host/common/File.cpp
+++ b/source/Host/common/File.cpp
@@ -24,10 +24,12 @@
#endif
#include "llvm/Support/ConvertUTF.h"
+#include "llvm/Support/Errno.h"
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Process.h" // for llvm::sys::Process::FileDescriptorHasColors()
#include "lldb/Host/Config.h"
+#include "lldb/Host/Host.h"
#include "lldb/Utility/DataBufferHeap.h"
#include "lldb/Utility/FileSpec.h"
#include "lldb/Utility/Log.h"
@@ -133,9 +135,8 @@ FILE *File::GetStream() {
m_should_close_fd = true;
}
- do {
- m_stream = ::fdopen(m_descriptor, mode);
- } while (m_stream == NULL && errno == EINTR);
+ m_stream =
+ llvm::sys::RetryAfterSignal(nullptr, ::fdopen, m_descriptor, mode);
// If we got a stream, then we own the stream and should no
// longer own the descriptor because fclose() will close it for us
@@ -157,6 +158,19 @@ void File::SetStream(FILE *fh, bool transfer_ownership) {
m_own_stream = transfer_ownership;
}
+static int DoOpen(const char *path, int flags, int mode) {
+#ifdef _MSC_VER
+ std::wstring wpath;
+ if (!llvm::ConvertUTF8toWide(path, wpath))
+ return -1;
+ int result;
+ ::_wsopen_s(&result, wpath.c_str(), flags, _SH_DENYNO, mode);
+ return result;
+#else
+ return ::open(path, flags, mode);
+#endif
+}
+
Status File::Open(const char *path, uint32_t options, uint32_t permissions) {
Status error;
if (IsValid())
@@ -222,20 +236,7 @@ Status File::Open(const char *path, uint32_t options, uint32_t permissions) {
mode |= S_IXOTH;
}
- do {
-#ifdef _MSC_VER
- std::wstring wpath;
- if (!llvm::ConvertUTF8toWide(path, wpath)) {
- m_descriptor = -1;
- error.SetErrorString("Error converting path to UTF-16");
- return error;
- }
- ::_wsopen_s(&m_descriptor, wpath.c_str(), oflag, _SH_DENYNO, mode);
-#else
- m_descriptor = ::open(path, oflag, mode);
-#endif
- } while (m_descriptor < 0 && errno == EINTR);
-
+ m_descriptor = llvm::sys::RetryAfterSignal(-1, DoOpen, path, oflag, mode);
if (!DescriptorIsValid())
error.SetErrorToErrno();
else {
@@ -421,12 +422,7 @@ off_t File::SeekFromEnd(off_t offset, Status *error_ptr) {
Status File::Flush() {
Status error;
if (StreamIsValid()) {
- int err = 0;
- do {
- err = ::fflush(m_stream);
- } while (err == EOF && errno == EINTR);
-
- if (err == EOF)
+ if (llvm::sys::RetryAfterSignal(EOF, ::fflush, m_stream) == EOF)
error.SetErrorToErrno();
} else if (!DescriptorIsValid()) {
error.SetErrorString("invalid file handle");
@@ -442,12 +438,7 @@ Status File::Sync() {
if (err == 0)
error.SetErrorToGenericError();
#else
- int err = 0;
- do {
- err = ::fsync(m_descriptor);
- } while (err == -1 && errno == EINTR);
-
- if (err == -1)
+ if (llvm::sys::RetryAfterSignal(-1, ::fsync, m_descriptor) == -1)
error.SetErrorToErrno();
#endif
} else {
@@ -497,10 +488,7 @@ Status File::Read(void *buf, size_t &num_bytes) {
ssize_t bytes_read = -1;
if (DescriptorIsValid()) {
- do {
- bytes_read = ::read(m_descriptor, buf, num_bytes);
- } while (bytes_read < 0 && errno == EINTR);
-
+ bytes_read = llvm::sys::RetryAfterSignal(-1, ::read, m_descriptor, buf, num_bytes);
if (bytes_read == -1) {
error.SetErrorToErrno();
num_bytes = 0;
@@ -559,10 +547,8 @@ Status File::Write(const void *buf, size_t &num_bytes) {
ssize_t bytes_written = -1;
if (DescriptorIsValid()) {
- do {
- bytes_written = ::write(m_descriptor, buf, num_bytes);
- } while (bytes_written < 0 && errno == EINTR);
-
+ bytes_written =
+ llvm::sys::RetryAfterSignal(-1, ::write, m_descriptor, buf, num_bytes);
if (bytes_written == -1) {
error.SetErrorToErrno();
num_bytes = 0;
@@ -624,11 +610,8 @@ Status File::Read(void *buf, size_t &num_bytes, off_t &offset) {
#ifndef _WIN32
int fd = GetDescriptor();
if (fd != kInvalidDescriptor) {
- ssize_t bytes_read = -1;
- do {
- bytes_read = ::pread(fd, buf, num_bytes, offset);
- } while (bytes_read < 0 && errno == EINTR);
-
+ ssize_t bytes_read =
+ llvm::sys::RetryAfterSignal(-1, ::pread, fd, buf, num_bytes, offset);
if (bytes_read < 0) {
num_bytes = 0;
error.SetErrorToErrno();
@@ -730,11 +713,8 @@ Status File::Write(const void *buf, size_t &num_bytes, off_t &offset) {
int fd = GetDescriptor();
if (fd != kInvalidDescriptor) {
#ifndef _WIN32
- ssize_t bytes_written = -1;
- do {
- bytes_written = ::pwrite(m_descriptor, buf, num_bytes, offset);
- } while (bytes_written < 0 && errno == EINTR);
-
+ ssize_t bytes_written =
+ llvm::sys::RetryAfterSignal(-1, ::pwrite, m_descriptor, buf, num_bytes, offset);
if (bytes_written < 0) {
num_bytes = 0;
error.SetErrorToErrno();
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
index 7de6f7fa865d..c0c4471e735f 100644
--- a/source/Host/common/MainLoop.cpp
+++ b/source/Host/common/MainLoop.cpp
@@ -193,10 +193,16 @@ Status MainLoop::RunImpl::Poll() {
void MainLoop::RunImpl::ProcessEvents() {
#ifdef FORCE_PSELECT
- for (const auto &fd : loop.m_read_fds) {
- if (!FD_ISSET(fd.first, &read_fd_set))
- continue;
- IOObject::WaitableHandle handle = fd.first;
+ // Collect first all readable file descriptors into a separate vector and then
+ // iterate over it to invoke callbacks. Iterating directly over
+ // loop.m_read_fds is not possible because the callbacks can modify the
+ // container which could invalidate the iterator.
+ std::vector<IOObject::WaitableHandle> fds;
+ for (const auto &fd : loop.m_read_fds)
+ if (FD_ISSET(fd.first, &read_fd_set))
+ fds.push_back(fd.first);
+
+ for (const auto &handle : fds) {
#else
for (const auto &fd : read_fds) {
if ((fd.revents & POLLIN) == 0)
@@ -209,13 +215,16 @@ void MainLoop::RunImpl::ProcessEvents() {
loop.ProcessReadObject(handle);
}
- for (const auto &entry : loop.m_signals) {
+ std::vector<int> signals;
+ for (const auto &entry : loop.m_signals)
+ if (g_signal_flags[entry.first] != 0)
+ signals.push_back(entry.first);
+
+ for (const auto &signal : signals) {
if (loop.m_terminate_request)
return;
- if (g_signal_flags[entry.first] == 0)
- continue; // No signal
- g_signal_flags[entry.first] = 0;
- loop.ProcessSignal(entry.first);
+ g_signal_flags[signal] = 0;
+ loop.ProcessSignal(signal);
}
}
#endif
diff --git a/source/Host/common/NativeProcessProtocol.cpp b/source/Host/common/NativeProcessProtocol.cpp
index 341c301dc9c5..b5b6e9d8b923 100644
--- a/source/Host/common/NativeProcessProtocol.cpp
+++ b/source/Host/common/NativeProcessProtocol.cpp
@@ -29,11 +29,13 @@ using namespace lldb_private;
// NativeProcessProtocol Members
// -----------------------------------------------------------------------------
-NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid)
- : m_pid(pid), m_threads(), m_current_thread_id(LLDB_INVALID_THREAD_ID),
- m_threads_mutex(), m_state(lldb::eStateInvalid), m_state_mutex(),
- m_delegates_mutex(), m_delegates(), m_breakpoint_list(),
- m_watchpoint_list(), m_terminal_fd(-1), m_stop_id(0) {}
+NativeProcessProtocol::NativeProcessProtocol(lldb::pid_t pid, int terminal_fd,
+ NativeDelegate &delegate)
+ : m_pid(pid), m_terminal_fd(terminal_fd) {
+ bool registered = RegisterNativeDelegate(delegate);
+ assert(registered);
+ (void)registered;
+}
lldb_private::Status NativeProcessProtocol::Interrupt() {
Status error;
@@ -488,23 +490,4 @@ Status NativeProcessProtocol::ResolveProcessArchitecture(lldb::pid_t pid,
"failed to retrieve a valid architecture from the exe module");
}
-#if !defined(__linux__) && !defined(__NetBSD__)
-// These need to be implemented to support lldb-gdb-server on a given platform.
-// Stubs are
-// provided to make the rest of the code link on non-supported platforms.
-
-Status NativeProcessProtocol::Launch(ProcessLaunchInfo &launch_info,
- NativeDelegate &native_delegate,
- MainLoop &mainloop,
- NativeProcessProtocolSP &process_sp) {
- llvm_unreachable("Platform has no NativeProcessProtocol support");
-}
-
-Status NativeProcessProtocol::Attach(lldb::pid_t pid,
- NativeDelegate &native_delegate,
- MainLoop &mainloop,
- NativeProcessProtocolSP &process_sp) {
- llvm_unreachable("Platform has no NativeProcessProtocol support");
-}
-
-#endif
+NativeProcessProtocol::Factory::~Factory() = default;
diff --git a/source/Host/common/SocketAddress.cpp b/source/Host/common/SocketAddress.cpp
index 440ae5d9027f..41150fa7fd74 100644
--- a/source/Host/common/SocketAddress.cpp
+++ b/source/Host/common/SocketAddress.cpp
@@ -201,7 +201,7 @@ const SocketAddress &SocketAddress::
operator=(const struct addrinfo *addr_info) {
Clear();
if (addr_info && addr_info->ai_addr && addr_info->ai_addrlen > 0 &&
- addr_info->ai_addrlen <= sizeof m_socket_addr) {
+ size_t(addr_info->ai_addrlen) <= sizeof m_socket_addr) {
::memcpy(&m_socket_addr, addr_info->ai_addr, addr_info->ai_addrlen);
}
return *this;
diff --git a/source/Host/macosx/Host.mm b/source/Host/macosx/Host.mm
index bbf70cd4c4b3..75624ef21f43 100644
--- a/source/Host/macosx/Host.mm
+++ b/source/Host/macosx/Host.mm
@@ -74,6 +74,7 @@
#include "lldb/Utility/StructuredData.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Errno.h"
#include "cfcpp/CFCBundle.h"
#include "cfcpp/CFCMutableArray.h"
@@ -1663,10 +1664,7 @@ HostThread Host::StartMonitoringChildProcess(
int wait_pid = 0;
bool cancel = false;
bool exited = false;
- do {
- wait_pid = ::waitpid(pid, &status, 0);
- } while (wait_pid < 0 && errno == EINTR);
-
+ wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &status, 0);
if (wait_pid >= 0) {
int signal = 0;
int exit_status = 0;
diff --git a/source/Host/posix/ConnectionFileDescriptorPosix.cpp b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
index 6b0f069c35a9..105ef0f23d46 100644
--- a/source/Host/posix/ConnectionFileDescriptorPosix.cpp
+++ b/source/Host/posix/ConnectionFileDescriptorPosix.cpp
@@ -245,11 +245,7 @@ ConnectionStatus ConnectionFileDescriptor::Connect(llvm::StringRef path,
} else if ((addr = GetURLAddress(path, FILE_SCHEME))) {
std::string addr_str = addr->str();
// file:///PATH
- int fd = -1;
- do {
- fd = ::open(addr_str.c_str(), O_RDWR);
- } while (fd == -1 && errno == EINTR);
-
+ int fd = llvm::sys::RetryAfterSignal(-1, ::open, addr_str.c_str(), O_RDWR);
if (fd == -1) {
if (error_ptr)
error_ptr->SetErrorToErrno();
@@ -620,20 +616,17 @@ ConnectionFileDescriptor::BytesAvailable(const Timeout<std::micro> &timeout,
if (select_helper.FDIsSetRead(pipe_fd)) {
// There is an interrupt or exit command in the command pipe
// Read the data from that pipe:
- char buffer[1];
-
- ssize_t bytes_read;
-
- do {
- bytes_read = ::read(pipe_fd, buffer, sizeof(buffer));
- } while (bytes_read < 0 && errno == EINTR);
+ char c;
- switch (buffer[0]) {
+ ssize_t bytes_read = llvm::sys::RetryAfterSignal(-1, ::read, pipe_fd, &c, 1);
+ assert(bytes_read == 1);
+ (void)bytes_read;
+ switch (c) {
case 'q':
if (log)
log->Printf("%p ConnectionFileDescriptor::BytesAvailable() "
"got data: %c from the command channel.",
- static_cast<void *>(this), buffer[0]);
+ static_cast<void *>(this), c);
return eConnectionStatusEndOfFile;
case 'i':
// Interrupt the current read
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
index d385b78e0ec4..5dbb3bb4ef7e 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.cpp
@@ -63,10 +63,10 @@ void AuxVector::ParseAuxv(DataExtractor &data) {
if (!ParseAuxvEntry(data, entry, &offset, byte_size))
break;
- if (entry.type == AT_NULL)
+ if (entry.type == AUXV_AT_NULL)
break;
- if (entry.type == AT_IGNORE)
+ if (entry.type == AUXV_AT_IGNORE)
continue;
m_auxv.push_back(entry);
@@ -110,43 +110,43 @@ void AuxVector::DumpToLog(Log *log) const {
const char *AuxVector::GetEntryName(EntryType type) {
const char *name = "AT_???";
-#define ENTRY_NAME(_type) \
- _type: \
- name = #_type
+#define ENTRY_NAME(_type) \
+ _type: \
+ name = #_type + 5
switch (type) {
- case ENTRY_NAME(AT_NULL); break;
- case ENTRY_NAME(AT_IGNORE); break;
- case ENTRY_NAME(AT_EXECFD); break;
- case ENTRY_NAME(AT_PHDR); break;
- case ENTRY_NAME(AT_PHENT); break;
- case ENTRY_NAME(AT_PHNUM); break;
- case ENTRY_NAME(AT_PAGESZ); break;
- case ENTRY_NAME(AT_BASE); break;
- case ENTRY_NAME(AT_FLAGS); break;
- case ENTRY_NAME(AT_ENTRY); break;
- case ENTRY_NAME(AT_NOTELF); break;
- case ENTRY_NAME(AT_UID); break;
- case ENTRY_NAME(AT_EUID); break;
- case ENTRY_NAME(AT_GID); break;
- case ENTRY_NAME(AT_EGID); break;
- case ENTRY_NAME(AT_CLKTCK); break;
- case ENTRY_NAME(AT_PLATFORM); break;
- case ENTRY_NAME(AT_HWCAP); break;
- case ENTRY_NAME(AT_FPUCW); break;
- case ENTRY_NAME(AT_DCACHEBSIZE); break;
- case ENTRY_NAME(AT_ICACHEBSIZE); break;
- case ENTRY_NAME(AT_UCACHEBSIZE); break;
- case ENTRY_NAME(AT_IGNOREPPC); break;
- case ENTRY_NAME(AT_SECURE); break;
- case ENTRY_NAME(AT_BASE_PLATFORM); break;
- case ENTRY_NAME(AT_RANDOM); break;
- case ENTRY_NAME(AT_EXECFN); break;
- case ENTRY_NAME(AT_SYSINFO); break;
- case ENTRY_NAME(AT_SYSINFO_EHDR); break;
- case ENTRY_NAME(AT_L1I_CACHESHAPE); break;
- case ENTRY_NAME(AT_L1D_CACHESHAPE); break;
- case ENTRY_NAME(AT_L2_CACHESHAPE); break;
- case ENTRY_NAME(AT_L3_CACHESHAPE); break;
+ case ENTRY_NAME(AUXV_AT_NULL); break;
+ case ENTRY_NAME(AUXV_AT_IGNORE); break;
+ case ENTRY_NAME(AUXV_AT_EXECFD); break;
+ case ENTRY_NAME(AUXV_AT_PHDR); break;
+ case ENTRY_NAME(AUXV_AT_PHENT); break;
+ case ENTRY_NAME(AUXV_AT_PHNUM); break;
+ case ENTRY_NAME(AUXV_AT_PAGESZ); break;
+ case ENTRY_NAME(AUXV_AT_BASE); break;
+ case ENTRY_NAME(AUXV_AT_FLAGS); break;
+ case ENTRY_NAME(AUXV_AT_ENTRY); break;
+ case ENTRY_NAME(AUXV_AT_NOTELF); break;
+ case ENTRY_NAME(AUXV_AT_UID); break;
+ case ENTRY_NAME(AUXV_AT_EUID); break;
+ case ENTRY_NAME(AUXV_AT_GID); break;
+ case ENTRY_NAME(AUXV_AT_EGID); break;
+ case ENTRY_NAME(AUXV_AT_CLKTCK); break;
+ case ENTRY_NAME(AUXV_AT_PLATFORM); break;
+ case ENTRY_NAME(AUXV_AT_HWCAP); break;
+ case ENTRY_NAME(AUXV_AT_FPUCW); break;
+ case ENTRY_NAME(AUXV_AT_DCACHEBSIZE); break;
+ case ENTRY_NAME(AUXV_AT_ICACHEBSIZE); break;
+ case ENTRY_NAME(AUXV_AT_UCACHEBSIZE); break;
+ case ENTRY_NAME(AUXV_AT_IGNOREPPC); break;
+ case ENTRY_NAME(AUXV_AT_SECURE); break;
+ case ENTRY_NAME(AUXV_AT_BASE_PLATFORM); break;
+ case ENTRY_NAME(AUXV_AT_RANDOM); break;
+ case ENTRY_NAME(AUXV_AT_EXECFN); break;
+ case ENTRY_NAME(AUXV_AT_SYSINFO); break;
+ case ENTRY_NAME(AUXV_AT_SYSINFO_EHDR); break;
+ case ENTRY_NAME(AUXV_AT_L1I_CACHESHAPE); break;
+ case ENTRY_NAME(AUXV_AT_L1D_CACHESHAPE); break;
+ case ENTRY_NAME(AUXV_AT_L2_CACHESHAPE); break;
+ case ENTRY_NAME(AUXV_AT_L3_CACHESHAPE); break;
}
#undef ENTRY_NAME
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
index 9c3e1b002a24..cf9da0808357 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/AuxVector.h
@@ -42,41 +42,42 @@ public:
/// Constants describing the type of entry.
/// On Linux, running "LD_SHOW_AUXV=1 ./executable" will spew AUX information.
+ /// Added AUXV prefix to avoid potential conflicts with system-defined macros
enum EntryType {
- AT_NULL = 0, ///< End of auxv.
- AT_IGNORE = 1, ///< Ignore entry.
- AT_EXECFD = 2, ///< File descriptor of program.
- AT_PHDR = 3, ///< Program headers.
- AT_PHENT = 4, ///< Size of program header.
- AT_PHNUM = 5, ///< Number of program headers.
- AT_PAGESZ = 6, ///< Page size.
- AT_BASE = 7, ///< Interpreter base address.
- AT_FLAGS = 8, ///< Flags.
- AT_ENTRY = 9, ///< Program entry point.
- AT_NOTELF = 10, ///< Set if program is not an ELF.
- AT_UID = 11, ///< UID.
- AT_EUID = 12, ///< Effective UID.
- AT_GID = 13, ///< GID.
- AT_EGID = 14, ///< Effective GID.
- AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)).
- AT_PLATFORM = 15, ///< String identifying platform.
- AT_HWCAP = 16, ///< Machine dependent hints about processor capabilities.
- AT_FPUCW = 18, ///< Used FPU control word.
- AT_DCACHEBSIZE = 19, ///< Data cache block size.
- AT_ICACHEBSIZE = 20, ///< Instruction cache block size.
- AT_UCACHEBSIZE = 21, ///< Unified cache block size.
- AT_IGNOREPPC = 22, ///< Entry should be ignored.
- AT_SECURE = 23, ///< Boolean, was exec setuid-like?
- AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
- AT_RANDOM = 25, ///< Address of 16 random bytes.
- AT_EXECFN = 31, ///< Filename of executable.
- AT_SYSINFO = 32, ///< Pointer to the global system page used for system
- ///calls and other nice things.
- AT_SYSINFO_EHDR = 33,
- AT_L1I_CACHESHAPE = 34, ///< Shapes of the caches.
- AT_L1D_CACHESHAPE = 35,
- AT_L2_CACHESHAPE = 36,
- AT_L3_CACHESHAPE = 37,
+ AUXV_AT_NULL = 0, ///< End of auxv.
+ AUXV_AT_IGNORE = 1, ///< Ignore entry.
+ AUXV_AT_EXECFD = 2, ///< File descriptor of program.
+ AUXV_AT_PHDR = 3, ///< Program headers.
+ AUXV_AT_PHENT = 4, ///< Size of program header.
+ AUXV_AT_PHNUM = 5, ///< Number of program headers.
+ AUXV_AT_PAGESZ = 6, ///< Page size.
+ AUXV_AT_BASE = 7, ///< Interpreter base address.
+ AUXV_AT_FLAGS = 8, ///< Flags.
+ AUXV_AT_ENTRY = 9, ///< Program entry point.
+ AUXV_AT_NOTELF = 10, ///< Set if program is not an ELF.
+ AUXV_AT_UID = 11, ///< UID.
+ AUXV_AT_EUID = 12, ///< Effective UID.
+ AUXV_AT_GID = 13, ///< GID.
+ AUXV_AT_EGID = 14, ///< Effective GID.
+ AUXV_AT_CLKTCK = 17, ///< Clock frequency (e.g. times(2)).
+ AUXV_AT_PLATFORM = 15, ///< String identifying platform.
+ AUXV_AT_HWCAP = 16, ///< Machine dependent hints about processor capabilities.
+ AUXV_AT_FPUCW = 18, ///< Used FPU control word.
+ AUXV_AT_DCACHEBSIZE = 19, ///< Data cache block size.
+ AUXV_AT_ICACHEBSIZE = 20, ///< Instruction cache block size.
+ AUXV_AT_UCACHEBSIZE = 21, ///< Unified cache block size.
+ AUXV_AT_IGNOREPPC = 22, ///< Entry should be ignored.
+ AUXV_AT_SECURE = 23, ///< Boolean, was exec setuid-like?
+ AUXV_AT_BASE_PLATFORM = 24, ///< String identifying real platforms.
+ AUXV_AT_RANDOM = 25, ///< Address of 16 random bytes.
+ AUXV_AT_EXECFN = 31, ///< Filename of executable.
+ AUXV_AT_SYSINFO = 32, ///< Pointer to the global system page used for system
+ ///calls and other nice things.
+ AUXV_AT_SYSINFO_EHDR = 33,
+ AUXV_AT_L1I_CACHESHAPE = 34, ///< Shapes of the caches.
+ AUXV_AT_L1D_CACHESHAPE = 35,
+ AUXV_AT_L2_CACHESHAPE = 36,
+ AUXV_AT_L3_CACHESHAPE = 37,
};
private:
diff --git a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
index 0092535648bd..a7afeb6d68c3 100644
--- a/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
+++ b/source/Plugins/DynamicLoader/POSIX-DYLD/DynamicLoaderPOSIXDYLD.cpp
@@ -576,7 +576,7 @@ addr_t DynamicLoaderPOSIXDYLD::ComputeLoadOffset() {
}
void DynamicLoaderPOSIXDYLD::EvalVdsoStatus() {
- AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_SYSINFO_EHDR);
+ AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AUXV_AT_SYSINFO_EHDR);
if (I != m_auxv->end())
m_vdso_base = I->value;
@@ -589,7 +589,7 @@ addr_t DynamicLoaderPOSIXDYLD::GetEntryPoint() {
if (m_auxv.get() == NULL)
return LLDB_INVALID_ADDRESS;
- AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AT_ENTRY);
+ AuxVector::iterator I = m_auxv->FindEntry(AuxVector::AUXV_AT_ENTRY);
if (I == m_auxv->end())
return LLDB_INVALID_ADDRESS;
diff --git a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
index af242d786a5f..9a6e39be0bfd 100644
--- a/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/ASan/ASanRuntime.cpp
@@ -247,12 +247,16 @@ bool AddressSanitizerRuntime::NotifyBreakpointHit(
AddressSanitizerRuntime *const instance =
static_cast<AddressSanitizerRuntime *>(baton);
+ ProcessSP process_sp = instance->GetProcessSP();
+
+ if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+ return false;
+
StructuredData::ObjectSP report = instance->RetrieveReportData();
std::string description;
if (report) {
description = instance->FormatDescription(report);
}
- ProcessSP process_sp = instance->GetProcessSP();
// Make sure this is the right process
if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) {
ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
diff --git a/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp b/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
index 3c22b81df7a4..eb238419ab18 100644
--- a/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/MainThreadChecker/MainThreadCheckerRuntime.cpp
@@ -141,7 +141,7 @@ MainThreadCheckerRuntime::RetrieveReportData(ExecutionContextRef exe_ctx_ref) {
d->AddStringItem("class_name", className);
d->AddStringItem("selector", selector);
d->AddStringItem("description",
- apiName + " must be called from main thread only");
+ apiName + " must be used from main thread only");
d->AddIntegerItem("tid", thread_sp->GetIndexID());
d->AddItem("trace", trace_sp);
return dict_sp;
@@ -163,6 +163,9 @@ bool MainThreadCheckerRuntime::NotifyBreakpointHit(
process_sp != context->exe_ctx_ref.GetProcessSP())
return false;
+ if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+ return false;
+
StructuredData::ObjectSP report =
instance->RetrieveReportData(context->exe_ctx_ref);
diff --git a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
index f60df0463346..cf9ba60c7b60 100644
--- a/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/TSan/TSanRuntime.cpp
@@ -803,6 +803,11 @@ bool ThreadSanitizerRuntime::NotifyBreakpointHit(
ThreadSanitizerRuntime *const instance =
static_cast<ThreadSanitizerRuntime *>(baton);
+ ProcessSP process_sp = instance->GetProcessSP();
+
+ if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+ return false;
+
StructuredData::ObjectSP report =
instance->RetrieveReportData(context->exe_ctx_ref);
std::string stop_reason_description;
@@ -851,7 +856,6 @@ bool ThreadSanitizerRuntime::NotifyBreakpointHit(
all_addresses_are_same);
}
- ProcessSP process_sp = instance->GetProcessSP();
// Make sure this is the right process
if (process_sp && process_sp == context->exe_ctx_ref.GetProcessSP()) {
ThreadSP thread_sp = context->exe_ctx_ref.GetThreadSP();
diff --git a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
index 023af84179aa..28c28e41ef44 100644
--- a/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
+++ b/source/Plugins/InstrumentationRuntime/UBSan/UBSanRuntime.cpp
@@ -217,6 +217,9 @@ bool UndefinedBehaviorSanitizerRuntime::NotifyBreakpointHit(
process_sp != context->exe_ctx_ref.GetProcessSP())
return false;
+ if (process_sp->GetModIDRef().IsLastResumeForUserExpression())
+ return false;
+
StructuredData::ObjectSP report =
instance->RetrieveReportData(context->exe_ctx_ref);
diff --git a/source/Plugins/Language/ObjC/Cocoa.cpp b/source/Plugins/Language/ObjC/Cocoa.cpp
index 2ba005e02ad4..8f4997533212 100644
--- a/source/Plugins/Language/ObjC/Cocoa.cpp
+++ b/source/Plugins/Language/ObjC/Cocoa.cpp
@@ -543,6 +543,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
}
uint64_t value = 0;
+ bool success = false;
switch (type_code) {
case TypeCodes::sint8:
value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 1, 0,
@@ -550,6 +551,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
if (error.Fail())
return false;
NSNumber_FormatChar(valobj, stream, (char)value, options.GetLanguage());
+ success = true;
break;
case TypeCodes::sint16:
value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 2, 0,
@@ -558,6 +560,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
return false;
NSNumber_FormatShort(valobj, stream, (short)value,
options.GetLanguage());
+ success = true;
break;
case TypeCodes::sint32:
value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 4, 0,
@@ -565,6 +568,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
if (error.Fail())
return false;
NSNumber_FormatInt(valobj, stream, (int)value, options.GetLanguage());
+ success = true;
break;
case TypeCodes::sint64:
value = process_sp->ReadUnsignedIntegerFromMemory(data_location, 8, 0,
@@ -572,6 +576,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
if (error.Fail())
return false;
NSNumber_FormatLong(valobj, stream, value, options.GetLanguage());
+ success = true;
break;
case TypeCodes::f32:
{
@@ -582,6 +587,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
float flt_value = 0.0f;
memcpy(&flt_value, &flt_as_int, sizeof(flt_as_int));
NSNumber_FormatFloat(valobj, stream, flt_value, options.GetLanguage());
+ success = true;
break;
}
case TypeCodes::f64:
@@ -593,6 +599,7 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
double dbl_value = 0.0;
memcpy(&dbl_value, &dbl_as_lng, sizeof(dbl_as_lng));
NSNumber_FormatDouble(valobj, stream, dbl_value, options.GetLanguage());
+ success = true;
break;
}
case TypeCodes::sint128: // internally, this is the same
@@ -608,12 +615,11 @@ bool lldb_private::formatters::NSNumberSummaryProvider(
return false;
llvm::APInt i128_value(128, words);
NSNumber_FormatInt128(valobj, stream, i128_value, options.GetLanguage());
+ success = true;
break;
}
- default:
- return false;
}
- return true;
+ return success;
}
}
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.cpp b/source/Plugins/Platform/Android/PlatformAndroid.cpp
index d896a9f99e63..0f37da60d5d6 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.cpp
+++ b/source/Plugins/Platform/Android/PlatformAndroid.cpp
@@ -366,13 +366,17 @@ bool PlatformAndroid::GetRemoteOSVersion() {
return m_major_os_version != 0;
}
-const char *PlatformAndroid::GetLibdlFunctionDeclarations() const {
- return R"(
+llvm::StringRef PlatformAndroid::GetLibdlFunctionDeclarations() {
+ // Older platform versions have the dl function symbols mangled
+ if (GetSdkVersion() < 26)
+ return R"(
extern "C" void* dlopen(const char*, int) asm("__dl_dlopen");
extern "C" void* dlsym(void*, const char*) asm("__dl_dlsym");
extern "C" int dlclose(void*) asm("__dl_dlclose");
extern "C" char* dlerror(void) asm("__dl_dlerror");
)";
+
+ return PlatformPOSIX::GetLibdlFunctionDeclarations();
}
AdbClient::SyncService *PlatformAndroid::GetSyncService(Status &error) {
diff --git a/source/Plugins/Platform/Android/PlatformAndroid.h b/source/Plugins/Platform/Android/PlatformAndroid.h
index 8fb4cc71a69f..638dba973369 100644
--- a/source/Plugins/Platform/Android/PlatformAndroid.h
+++ b/source/Plugins/Platform/Android/PlatformAndroid.h
@@ -76,7 +76,7 @@ protected:
Status DownloadSymbolFile(const lldb::ModuleSP &module_sp,
const FileSpec &dst_file_spec) override;
- const char *GetLibdlFunctionDeclarations() const override;
+ llvm::StringRef GetLibdlFunctionDeclarations() override;
private:
AdbClient::SyncService *GetSyncService(Status &error);
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
index f4cf22ad7583..013c33def13b 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.cpp
@@ -884,7 +884,7 @@ void PlatformPOSIX::CalculateTrapHandlerSymbolNames() {
Status PlatformPOSIX::EvaluateLibdlExpression(
lldb_private::Process *process, const char *expr_cstr,
- const char *expr_prefix, lldb::ValueObjectSP &result_valobj_sp) {
+ llvm::StringRef expr_prefix, lldb::ValueObjectSP &result_valobj_sp) {
DynamicLoader *loader = process->GetDynamicLoader();
if (loader) {
Status error = loader->CanLoadImage();
@@ -944,7 +944,7 @@ uint32_t PlatformPOSIX::DoLoadImage(lldb_private::Process *process,
the_result;
)",
path);
- const char *prefix = GetLibdlFunctionDeclarations();
+ llvm::StringRef prefix = GetLibdlFunctionDeclarations();
lldb::ValueObjectSP result_valobj_sp;
error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
result_valobj_sp);
@@ -992,7 +992,7 @@ Status PlatformPOSIX::UnloadImage(lldb_private::Process *process,
StreamString expr;
expr.Printf("dlclose((void *)0x%" PRIx64 ")", image_addr);
- const char *prefix = GetLibdlFunctionDeclarations();
+ llvm::StringRef prefix = GetLibdlFunctionDeclarations();
lldb::ValueObjectSP result_valobj_sp;
Status error = EvaluateLibdlExpression(process, expr.GetData(), prefix,
result_valobj_sp);
@@ -1024,7 +1024,7 @@ lldb::ProcessSP PlatformPOSIX::ConnectProcess(llvm::StringRef connect_url,
error);
}
-const char *PlatformPOSIX::GetLibdlFunctionDeclarations() const {
+llvm::StringRef PlatformPOSIX::GetLibdlFunctionDeclarations() {
return R"(
extern "C" void* dlopen(const char*, int);
extern "C" void* dlsym(void*, const char*);
diff --git a/source/Plugins/Platform/POSIX/PlatformPOSIX.h b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
index 742702b07b88..ebc36c2461db 100644
--- a/source/Plugins/Platform/POSIX/PlatformPOSIX.h
+++ b/source/Plugins/Platform/POSIX/PlatformPOSIX.h
@@ -198,10 +198,10 @@ protected:
lldb_private::Status
EvaluateLibdlExpression(lldb_private::Process *process, const char *expr_cstr,
- const char *expr_prefix,
+ llvm::StringRef expr_prefix,
lldb::ValueObjectSP &result_valobj_sp);
- virtual const char *GetLibdlFunctionDeclarations() const;
+ virtual llvm::StringRef GetLibdlFunctionDeclarations();
private:
DISALLOW_COPY_AND_ASSIGN(PlatformPOSIX);
diff --git a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
index 10dd14753914..a4f5f02dde62 100644
--- a/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
+++ b/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp
@@ -746,15 +746,9 @@ ProcessMonitor::ProcessMonitor(
if (!error.Success())
return;
-WAIT_AGAIN:
- // Wait for the operation thread to initialize.
- if (sem_wait(&args->m_semaphore)) {
- if (errno == EINTR)
- goto WAIT_AGAIN;
- else {
- error.SetErrorToErrno();
- return;
- }
+ if (llvm::sys::RetryAfterSignal(-1, sem_wait, &args->m_semaphore) == -1) {
+ error.SetErrorToErrno();
+ return;
}
// Check that the launch was a success.
@@ -790,15 +784,9 @@ ProcessMonitor::ProcessMonitor(ProcessFreeBSD *process, lldb::pid_t pid,
if (!error.Success())
return;
-WAIT_AGAIN:
- // Wait for the operation thread to initialize.
- if (sem_wait(&args->m_semaphore)) {
- if (errno == EINTR)
- goto WAIT_AGAIN;
- else {
- error.SetErrorToErrno();
- return;
- }
+ if (llvm::sys::RetryAfterSignal(-1, sem_wait, &args->m_semaphore) == -1) {
+ error.SetErrorToErrno();
+ return;
}
// Check that the attach was a success.
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index 8e378802de9c..d988ee93a2bc 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -214,207 +214,122 @@ static Status EnsureFDFlags(int fd, int flags) {
// Public Static Methods
// -----------------------------------------------------------------------------
-Status NativeProcessProtocol::Launch(
- ProcessLaunchInfo &launch_info,
- NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
- NativeProcessProtocolSP &native_process_sp) {
+llvm::Expected<NativeProcessProtocolSP>
+NativeProcessLinux::Factory::Launch(ProcessLaunchInfo &launch_info,
+ NativeDelegate &native_delegate,
+ MainLoop &mainloop) const {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- Status error;
+ MaybeLogLaunchInfo(launch_info);
- // Verify the working directory is valid if one was specified.
- FileSpec working_dir{launch_info.GetWorkingDirectory()};
- if (working_dir && (!working_dir.ResolvePath() ||
- !llvm::sys::fs::is_directory(working_dir.GetPath()))) {
- error.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return error;
+ Status status;
+ ::pid_t pid = ProcessLauncherPosixFork()
+ .LaunchProcess(launch_info, status)
+ .GetProcessId();
+ LLDB_LOG(log, "pid = {0:x}", pid);
+ if (status.Fail()) {
+ LLDB_LOG(log, "failed to launch process: {0}", status);
+ return status.ToError();
}
- // Create the NativeProcessLinux in launch mode.
- native_process_sp.reset(new NativeProcessLinux());
-
- if (!native_process_sp->RegisterNativeDelegate(native_delegate)) {
- native_process_sp.reset();
- error.SetErrorStringWithFormat("failed to register the native delegate");
- return error;
+ // Wait for the child process to trap on its call to execve.
+ int wstatus;
+ ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+ assert(wpid == pid);
+ (void)wpid;
+ if (!WIFSTOPPED(wstatus)) {
+ LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+ return llvm::make_error<StringError>("Could not sync with inferior process",
+ llvm::inconvertibleErrorCode());
}
+ LLDB_LOG(log, "inferior started, now in stopped state");
- error = std::static_pointer_cast<NativeProcessLinux>(native_process_sp)
- ->LaunchInferior(mainloop, launch_info);
+ ArchSpec arch;
+ if ((status = ResolveProcessArchitecture(pid, arch)).Fail())
+ return status.ToError();
- if (error.Fail()) {
- native_process_sp.reset();
- LLDB_LOG(log, "failed to launch process: {0}", error);
- return error;
- }
+ // Set the architecture to the exe architecture.
+ LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
+ arch.GetArchitectureName());
- launch_info.SetProcessID(native_process_sp->GetID());
+ status = SetDefaultPtraceOpts(pid);
+ if (status.Fail()) {
+ LLDB_LOG(log, "failed to set default ptrace options: {0}", status);
+ return status.ToError();
+ }
- return error;
+ std::shared_ptr<NativeProcessLinux> process_sp(new NativeProcessLinux(
+ pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
+ arch, mainloop));
+ process_sp->InitializeThreads({pid});
+ return process_sp;
}
-Status NativeProcessProtocol::Attach(
+llvm::Expected<NativeProcessProtocolSP> NativeProcessLinux::Factory::Attach(
lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
+ MainLoop &mainloop) const {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
LLDB_LOG(log, "pid = {0:x}", pid);
// Retrieve the architecture for the running process.
- ArchSpec process_arch;
- Status error = ResolveProcessArchitecture(pid, process_arch);
- if (!error.Success())
- return error;
+ ArchSpec arch;
+ Status status = ResolveProcessArchitecture(pid, arch);
+ if (!status.Success())
+ return status.ToError();
- std::shared_ptr<NativeProcessLinux> native_process_linux_sp(
- new NativeProcessLinux());
+ auto tids_or = NativeProcessLinux::Attach(pid);
+ if (!tids_or)
+ return tids_or.takeError();
- if (!native_process_linux_sp->RegisterNativeDelegate(native_delegate)) {
- error.SetErrorStringWithFormat("failed to register the native delegate");
- return error;
- }
-
- native_process_linux_sp->AttachToInferior(mainloop, pid, error);
- if (!error.Success())
- return error;
-
- native_process_sp = native_process_linux_sp;
- return error;
+ std::shared_ptr<NativeProcessLinux> process_sp(
+ new NativeProcessLinux(pid, -1, native_delegate, arch, mainloop));
+ process_sp->InitializeThreads(*tids_or);
+ return process_sp;
}
// -----------------------------------------------------------------------------
// Public Instance Methods
// -----------------------------------------------------------------------------
-NativeProcessLinux::NativeProcessLinux()
- : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID), m_arch(),
- m_supports_mem_region(eLazyBoolCalculate), m_mem_region_cache(),
- m_pending_notification_tid(LLDB_INVALID_THREAD_ID),
- m_pt_proces_trace_id(LLDB_INVALID_UID) {}
-
-void NativeProcessLinux::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
- Status &error) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "pid = {0:x}", pid);
+NativeProcessLinux::NativeProcessLinux(::pid_t pid, int terminal_fd,
+ NativeDelegate &delegate,
+ const ArchSpec &arch, MainLoop &mainloop)
+ : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
+ if (m_terminal_fd != -1) {
+ Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
+ assert(status.Success());
+ }
+ Status status;
m_sigchld_handle = mainloop.RegisterSignal(
- SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
- if (!m_sigchld_handle)
- return;
-
- error = ResolveProcessArchitecture(pid, m_arch);
- if (!error.Success())
- return;
-
- // Set the architecture to the exe architecture.
- LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
- m_arch.GetArchitectureName());
- m_pid = pid;
- SetState(eStateAttaching);
-
- Attach(pid, error);
+ SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+ assert(m_sigchld_handle && status.Success());
}
-Status NativeProcessLinux::LaunchInferior(MainLoop &mainloop,
- ProcessLaunchInfo &launch_info) {
- Status error;
- m_sigchld_handle = mainloop.RegisterSignal(
- SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
- if (!m_sigchld_handle)
- return error;
-
- SetState(eStateLaunching);
-
- MaybeLogLaunchInfo(launch_info);
-
- ::pid_t pid =
- ProcessLauncherPosixFork().LaunchProcess(launch_info, error).GetProcessId();
- if (error.Fail())
- return error;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- // Wait for the child process to trap on its call to execve.
- ::pid_t wpid;
- int status;
- if ((wpid = waitpid(pid, &status, 0)) < 0) {
- error.SetErrorToErrno();
- LLDB_LOG(log, "waitpid for inferior failed with %s", error);
-
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now,
- // using eStateInvalid.
- SetState(StateType::eStateInvalid);
-
- return error;
- }
- assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
- "Could not sync with inferior process.");
-
- LLDB_LOG(log, "inferior started, now in stopped state");
- error = SetDefaultPtraceOpts(pid);
- if (error.Fail()) {
- LLDB_LOG(log, "failed to set default ptrace options: {0}", error);
-
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For now,
- // using eStateInvalid.
- SetState(StateType::eStateInvalid);
-
- return error;
- }
-
- // Release the master terminal descriptor and pass it off to the
- // NativeProcessLinux instance. Similarly stash the inferior pid.
- m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- m_pid = pid;
- launch_info.SetProcessID(pid);
-
- if (m_terminal_fd != -1) {
- error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
- if (error.Fail()) {
- LLDB_LOG(log,
- "inferior EnsureFDFlags failed for ensuring terminal "
- "O_NONBLOCK setting: {0}",
- error);
-
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For
- // now, using eStateInvalid.
- SetState(StateType::eStateInvalid);
-
- return error;
- }
+void NativeProcessLinux::InitializeThreads(llvm::ArrayRef<::pid_t> tids) {
+ for (const auto &tid : tids) {
+ NativeThreadLinuxSP thread_sp = AddThread(tid);
+ assert(thread_sp && "AddThread() returned a nullptr thread");
+ thread_sp->SetStoppedBySignal(SIGSTOP);
+ ThreadWasCreated(*thread_sp);
}
- LLDB_LOG(log, "adding pid = {0}", pid);
- ResolveProcessArchitecture(m_pid, m_arch);
- NativeThreadLinuxSP thread_sp = AddThread(pid);
- assert(thread_sp && "AddThread() returned a nullptr thread");
- thread_sp->SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(*thread_sp);
-
// Let our process instance know the thread has stopped.
- SetCurrentThreadID(thread_sp->GetID());
- SetState(StateType::eStateStopped);
+ SetCurrentThreadID(tids[0]);
+ SetState(StateType::eStateStopped, false);
- if (error.Fail())
- LLDB_LOG(log, "inferior launching failed {0}", error);
- return error;
+ // Proccess any signals we received before installing our handler
+ SigchldHandler();
}
-::pid_t NativeProcessLinux::Attach(lldb::pid_t pid, Status &error) {
+llvm::Expected<std::vector<::pid_t>> NativeProcessLinux::Attach(::pid_t pid) {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
+ Status status;
// Use a map to keep track of the threads which we have attached/need to
// attach.
Host::TidMap tids_to_attach;
- if (pid <= 1) {
- error.SetErrorToGenericError();
- error.SetErrorString("Attaching to process 1 is not allowed.");
- return -1;
- }
-
while (Host::FindProcessThreads(pid, tids_to_attach)) {
for (Host::TidMap::iterator it = tids_to_attach.begin();
it != tids_to_attach.end();) {
@@ -423,48 +338,36 @@ Status NativeProcessLinux::LaunchInferior(MainLoop &mainloop,
// Attach to the requested process.
// An attach will cause the thread to stop with a SIGSTOP.
- error = PtraceWrapper(PTRACE_ATTACH, tid);
- if (error.Fail()) {
+ if ((status = PtraceWrapper(PTRACE_ATTACH, tid)).Fail()) {
// No such thread. The thread may have exited.
// More error handling may be needed.
- if (error.GetError() == ESRCH) {
+ if (status.GetError() == ESRCH) {
it = tids_to_attach.erase(it);
continue;
- } else
- return -1;
+ }
+ return status.ToError();
}
- int status;
+ int wpid =
+ llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, nullptr, __WALL);
// Need to use __WALL otherwise we receive an error with errno=ECHLD
// At this point we should have a thread stopped if waitpid succeeds.
- if ((status = waitpid(tid, NULL, __WALL)) < 0) {
+ if (wpid < 0) {
// No such thread. The thread may have exited.
// More error handling may be needed.
if (errno == ESRCH) {
it = tids_to_attach.erase(it);
continue;
- } else {
- error.SetErrorToErrno();
- return -1;
}
+ return llvm::errorCodeToError(
+ std::error_code(errno, std::generic_category()));
}
- error = SetDefaultPtraceOpts(tid);
- if (error.Fail())
- return -1;
+ if ((status = SetDefaultPtraceOpts(tid)).Fail())
+ return status.ToError();
LLDB_LOG(log, "adding tid = {0}", tid);
it->second = true;
-
- // Create the thread, mark it as stopped.
- NativeThreadLinuxSP thread_sp(AddThread(static_cast<lldb::tid_t>(tid)));
- assert(thread_sp && "AddThread() returned a nullptr");
-
- // This will notify this is a new thread and tell the system it is
- // stopped.
- thread_sp->SetStoppedBySignal(SIGSTOP);
- ThreadWasCreated(*thread_sp);
- SetCurrentThreadID(thread_sp->GetID());
}
// move the loop forward
@@ -472,17 +375,16 @@ Status NativeProcessLinux::LaunchInferior(MainLoop &mainloop,
}
}
- if (tids_to_attach.size() > 0) {
- m_pid = pid;
- // Let our process instance know the thread has stopped.
- SetState(StateType::eStateStopped);
- } else {
- error.SetErrorToGenericError();
- error.SetErrorString("No such process.");
- return -1;
- }
+ size_t tid_count = tids_to_attach.size();
+ if (tid_count == 0)
+ return llvm::make_error<StringError>("No such process",
+ llvm::inconvertibleErrorCode());
- return pid;
+ std::vector<::pid_t> tids;
+ tids.reserve(tid_count);
+ for (const auto &p : tids_to_attach)
+ tids.push_back(p.first);
+ return std::move(tids);
}
Status NativeProcessLinux::SetDefaultPtraceOpts(lldb::pid_t pid) {
@@ -662,14 +564,11 @@ void NativeProcessLinux::WaitForNewThread(::pid_t tid) {
// The thread is not tracked yet, let's wait for it to appear.
int status = -1;
- ::pid_t wait_pid;
- do {
- LLDB_LOG(log,
- "received thread creation event for tid {0}. tid not tracked "
- "yet, waiting for thread to appear...",
- tid);
- wait_pid = waitpid(tid, &status, __WALL);
- } while (wait_pid == -1 && errno == EINTR);
+ LLDB_LOG(log,
+ "received thread creation event for tid {0}. tid not tracked "
+ "yet, waiting for thread to appear...",
+ tid);
+ ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, tid, &status, __WALL);
// Since we are waiting on a specific tid, this must be the creation event.
// But let's do some checks just in case.
if (wait_pid != tid) {
@@ -897,11 +796,9 @@ void NativeProcessLinux::MonitorSIGTRAP(const siginfo_t &info,
break;
default:
- LLDB_LOG(
- log,
- "received unknown SIGTRAP stop event ({0}, pid {1} tid {2}, resuming",
- info.si_code, GetID(), thread.GetID());
- llvm_unreachable("Unexpected SIGTRAP code!");
+ LLDB_LOG(log, "received unknown SIGTRAP stop event ({0}, pid {1} tid {2}",
+ info.si_code, GetID(), thread.GetID());
+ MonitorSignal(info, thread, false);
break;
}
}
@@ -2363,15 +2260,13 @@ void NativeProcessLinux::SigchldHandler() {
// Process all pending waitpid notifications.
while (true) {
int status = -1;
- ::pid_t wait_pid = waitpid(-1, &status, __WALL | __WNOTHREAD | WNOHANG);
+ ::pid_t wait_pid = llvm::sys::RetryAfterSignal(-1, ::waitpid, -1, &status,
+ __WALL | __WNOTHREAD | WNOHANG);
if (wait_pid == 0)
break; // We are done.
if (wait_pid == -1) {
- if (errno == EINTR)
- continue;
-
Status error(errno, eErrorTypePOSIX);
LLDB_LOG(log, "waitpid (-1, &status, _) failed: {0}", error);
break;
diff --git a/source/Plugins/Process/Linux/NativeProcessLinux.h b/source/Plugins/Process/Linux/NativeProcessLinux.h
index 6bf093f6a39a..9584713d3654 100644
--- a/source/Plugins/Process/Linux/NativeProcessLinux.h
+++ b/source/Plugins/Process/Linux/NativeProcessLinux.h
@@ -39,15 +39,18 @@ namespace process_linux {
///
/// Changes in the inferior process state are broadcasted.
class NativeProcessLinux : public NativeProcessProtocol {
- friend Status NativeProcessProtocol::Launch(
- ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+public:
+ class Factory : public NativeProcessProtocol::Factory {
+ public:
+ llvm::Expected<NativeProcessProtocolSP>
+ Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+ MainLoop &mainloop) const override;
- friend Status NativeProcessProtocol::Attach(
- lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+ llvm::Expected<NativeProcessProtocolSP>
+ Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
+ MainLoop &mainloop) const override;
+ };
-public:
// ---------------------------------------------------------------------
// NativeProcessProtocol Interface
// ---------------------------------------------------------------------
@@ -144,10 +147,10 @@ private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
- LazyBool m_supports_mem_region;
+ LazyBool m_supports_mem_region = eLazyBoolCalculate;
std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
- lldb::tid_t m_pending_notification_tid;
+ lldb::tid_t m_pending_notification_tid = LLDB_INVALID_THREAD_ID;
// List of thread ids stepping with a breakpoint with the address of
// the relevan breakpoint
@@ -156,19 +159,15 @@ private:
// ---------------------------------------------------------------------
// Private Instance Methods
// ---------------------------------------------------------------------
- NativeProcessLinux();
-
- Status LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
-
- /// Attaches to an existing process. Forms the
- /// implementation of Process::DoAttach
- void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Status &error);
+ NativeProcessLinux(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
+ const ArchSpec &arch, MainLoop &mainloop);
- ::pid_t Attach(lldb::pid_t pid, Status &error);
+ // Returns a list of process threads that we have attached to.
+ static llvm::Expected<std::vector<::pid_t>> Attach(::pid_t pid);
static Status SetDefaultPtraceOpts(const lldb::pid_t);
- static void *MonitorThread(void *baton);
+ void InitializeThreads(llvm::ArrayRef<::pid_t> tids);
void MonitorCallback(lldb::pid_t pid, bool exited, WaitStatus status);
@@ -280,7 +279,7 @@ private:
// same process user id.
llvm::DenseSet<lldb::tid_t> m_pt_traced_thread_group;
- lldb::user_id_t m_pt_proces_trace_id;
+ lldb::user_id_t m_pt_proces_trace_id = LLDB_INVALID_UID;
TraceOptions m_pt_process_trace_config;
};
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
index c3b58f16256a..1a5b304ac697 100644
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_arm64.cpp
@@ -680,7 +680,7 @@ Status NativeRegisterContextLinux_arm64::ClearAllHardwareWatchpoints() {
return error;
lldb::addr_t tempAddr = 0;
- uint32_t tempControl = 0, tempRefCount = 0;
+ uint32_t tempControl = 0;
for (uint32_t i = 0; i < m_max_hwp_supported; i++) {
if (m_hwp_regs[i].control & 0x01) {
@@ -858,7 +858,7 @@ Status NativeRegisterContextLinux_arm64::DoReadRegisterValue(
RegisterValue &value) {
Status error;
if (offset > sizeof(struct user_pt_regs)) {
- uintptr_t offset = offset - sizeof(struct user_pt_regs);
+ offset -= sizeof(struct user_pt_regs);
if (offset > sizeof(struct user_fpsimd_state)) {
error.SetErrorString("invalid offset value");
return error;
@@ -905,7 +905,7 @@ Status NativeRegisterContextLinux_arm64::DoWriteRegisterValue(
Status error;
::pid_t tid = m_thread.GetID();
if (offset > sizeof(struct user_pt_regs)) {
- uintptr_t offset = offset - sizeof(struct user_pt_regs);
+ offset -= sizeof(struct user_pt_regs);
if (offset > sizeof(struct user_fpsimd_state)) {
error.SetErrorString("invalid offset value");
return error;
diff --git a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
index 59dc9e9f7d45..e44e03b46b5c 100755
--- a/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
+++ b/source/Plugins/Process/Linux/NativeRegisterContextLinux_x86_64.cpp
@@ -646,13 +646,6 @@ Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
Status error;
data_sp.reset(new DataBufferHeap(REG_CONTEXT_SIZE, 0));
- if (!data_sp) {
- error.SetErrorStringWithFormat(
- "failed to allocate DataBufferHeap instance of size %" PRIu64,
- REG_CONTEXT_SIZE);
- return error;
- }
-
error = ReadGPR();
if (error.Fail())
return error;
@@ -662,13 +655,6 @@ Status NativeRegisterContextLinux_x86_64::ReadAllRegisterValues(
return error;
uint8_t *dst = data_sp->GetBytes();
- if (dst == nullptr) {
- error.SetErrorStringWithFormat("DataBufferHeap instance of size %" PRIu64
- " returned a null pointer",
- REG_CONTEXT_SIZE);
- return error;
- }
-
::memcpy(dst, &m_gpr_x86_64, GetRegisterInfoInterface().GetGPRSize());
dst += GetRegisterInfoInterface().GetGPRSize();
if (m_xstate_type == XStateType::FXSAVE)
@@ -741,10 +727,9 @@ Status NativeRegisterContextLinux_x86_64::WriteAllRegisterValues(
}
if (data_sp->GetByteSize() != REG_CONTEXT_SIZE) {
- error.SetErrorStringWithFormat(
- "NativeRegisterContextLinux_x86_64::%s data_sp contained mismatched "
- "data size, expected %" PRIu64 ", actual %" PRIu64,
- __FUNCTION__, REG_CONTEXT_SIZE, data_sp->GetByteSize());
+ error.SetErrorStringWithFormatv(
+ "data_sp contained mismatched data size, expected {0}, actual {1}",
+ REG_CONTEXT_SIZE, data_sp->GetByteSize());
return error;
}
diff --git a/source/Plugins/Process/Linux/ProcessorTrace.cpp b/source/Plugins/Process/Linux/ProcessorTrace.cpp
index 7043d50256e6..505c526ab70d 100644
--- a/source/Plugins/Process/Linux/ProcessorTrace.cpp
+++ b/source/Plugins/Process/Linux/ProcessorTrace.cpp
@@ -46,13 +46,11 @@ Status ProcessorTraceMonitor::GetTraceConfig(TraceOptions &config) const {
Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
const TraceOptions &config) {
- Status error;
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- LLDB_LOG(log, "{0}", config.getThreadID());
-
#ifndef PERF_ATTR_SIZE_VER5
llvm_unreachable("perf event not supported");
#else
+ Status error;
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
LLDB_LOG(log, "called thread id {0}", tid);
uint64_t page_size = getpagesize();
@@ -61,12 +59,11 @@ Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
uint64_t numpages = static_cast<uint64_t>(
llvm::PowerOf2Floor((bufsize + page_size - 1) / page_size));
- numpages = std::max(1ul, numpages);
+ numpages = std::max<uint64_t>(1, numpages);
bufsize = page_size * numpages;
numpages = static_cast<uint64_t>(
llvm::PowerOf2Floor((metabufsize + page_size - 1) / page_size));
- numpages = std::max(0ul, numpages);
metabufsize = page_size * numpages;
perf_event_attr attr;
@@ -117,7 +114,7 @@ Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
return error;
}
- m_fd = std::move(std::unique_ptr<int, file_close>(new int(fd), file_close()));
+ m_fd = std::unique_ptr<int, file_close>(new int(fd), file_close());
errno = 0;
auto base =
@@ -129,9 +126,9 @@ Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
return error;
}
- m_mmap_meta = std::move(std::unique_ptr<perf_event_mmap_page, munmap_delete>(
+ m_mmap_meta = std::unique_ptr<perf_event_mmap_page, munmap_delete>(
reinterpret_cast<perf_event_mmap_page *>(base),
- munmap_delete(metabufsize + page_size)));
+ munmap_delete(metabufsize + page_size));
m_mmap_meta->aux_offset = m_mmap_meta->data_offset + m_mmap_meta->data_size;
m_mmap_meta->aux_size = bufsize;
@@ -145,10 +142,10 @@ Status ProcessorTraceMonitor::StartTrace(lldb::pid_t pid, lldb::tid_t tid,
error.SetErrorString("Trace buffer allocation failed");
return error;
}
- m_mmap_aux = std::move(std::unique_ptr<uint8_t, munmap_delete>(
- reinterpret_cast<uint8_t *>(mmap_aux), munmap_delete(bufsize)));
-#endif
+ m_mmap_aux = std::unique_ptr<uint8_t, munmap_delete>(
+ reinterpret_cast<uint8_t *>(mmap_aux), munmap_delete(bufsize));
return error;
+#endif
}
llvm::MutableArrayRef<uint8_t> ProcessorTraceMonitor::GetDataBuffer() {
@@ -251,14 +248,14 @@ ProcessorTraceMonitor::Create(lldb::pid_t pid, lldb::tid_t tid,
Status error;
if (tid == LLDB_INVALID_THREAD_ID) {
error.SetErrorString("thread not specified");
- return std::move(error.ToError());
+ return error.ToError();
}
ProcessorTraceMonitorUP pt_monitor_up(new ProcessorTraceMonitor);
error = pt_monitor_up->StartTrace(pid, tid, config);
if (error.Fail())
- return std::move(error.ToError());
+ return error.ToError();
pt_monitor_up->SetThreadID(tid);
@@ -274,13 +271,11 @@ ProcessorTraceMonitor::Create(lldb::pid_t pid, lldb::tid_t tid,
Status
ProcessorTraceMonitor::ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
size_t offset) {
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- Status error;
-
#ifndef PERF_ATTR_SIZE_VER5
llvm_unreachable("perf event not supported");
#else
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+ Status error;
uint64_t head = m_mmap_meta->aux_head;
LLDB_LOG(log, "Aux size -{0} , Head - {1}", m_mmap_meta->aux_size, head);
@@ -306,12 +301,12 @@ ProcessorTraceMonitor::ReadPerfTraceAux(llvm::MutableArrayRef<uint8_t> &buffer,
Status
ProcessorTraceMonitor::ReadPerfTraceData(llvm::MutableArrayRef<uint8_t> &buffer,
size_t offset) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
- uint64_t bytes_remaining = buffer.size();
- Status error;
#ifndef PERF_ATTR_SIZE_VER5
llvm_unreachable("perf event not supported");
#else
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PTRACE));
+ uint64_t bytes_remaining = buffer.size();
+ Status error;
uint64_t head = m_mmap_meta->data_head;
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index a4d775860a65..b9ef02efa65d 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -21,6 +21,7 @@
#include "lldb/Host/common/NativeRegisterContext.h"
#include "lldb/Host/posix/ProcessLauncherPosixFork.h"
#include "lldb/Target/Process.h"
+#include "llvm/Support/Errno.h"
// System includes - They have to be included after framework includes because
// they define some
@@ -63,81 +64,101 @@ static Status EnsureFDFlags(int fd, int flags) {
// Public Static Methods
// -----------------------------------------------------------------------------
-Status NativeProcessProtocol::Launch(
- ProcessLaunchInfo &launch_info,
- NativeProcessProtocol::NativeDelegate &native_delegate, MainLoop &mainloop,
- NativeProcessProtocolSP &native_process_sp) {
+llvm::Expected<NativeProcessProtocolSP>
+NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
+ NativeDelegate &native_delegate,
+ MainLoop &mainloop) const {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- Status error;
+ Status status;
+ ::pid_t pid = ProcessLauncherPosixFork()
+ .LaunchProcess(launch_info, status)
+ .GetProcessId();
+ LLDB_LOG(log, "pid = {0:x}", pid);
+ if (status.Fail()) {
+ LLDB_LOG(log, "failed to launch process: {0}", status);
+ return status.ToError();
+ }
- // Verify the working directory is valid if one was specified.
- FileSpec working_dir{launch_info.GetWorkingDirectory()};
- if (working_dir && (!working_dir.ResolvePath() ||
- !llvm::sys::fs::is_directory(working_dir.GetPath()))) {
- error.SetErrorStringWithFormat("No such file or directory: %s",
- working_dir.GetCString());
- return error;
+ // Wait for the child process to trap on its call to execve.
+ int wstatus;
+ ::pid_t wpid = llvm::sys::RetryAfterSignal(-1, ::waitpid, pid, &wstatus, 0);
+ assert(wpid == pid);
+ (void)wpid;
+ if (!WIFSTOPPED(wstatus)) {
+ LLDB_LOG(log, "Could not sync with inferior process: wstatus={1}",
+ WaitStatus::Decode(wstatus));
+ return llvm::make_error<StringError>("Could not sync with inferior process",
+ llvm::inconvertibleErrorCode());
}
+ LLDB_LOG(log, "inferior started, now in stopped state");
- // Create the NativeProcessNetBSD in launch mode.
- native_process_sp.reset(new NativeProcessNetBSD());
+ ArchSpec arch;
+ if ((status = ResolveProcessArchitecture(pid, arch)).Fail())
+ return status.ToError();
- if (!native_process_sp->RegisterNativeDelegate(native_delegate)) {
- native_process_sp.reset();
- error.SetErrorStringWithFormat("failed to register the native delegate");
- return error;
- }
+ // Set the architecture to the exe architecture.
+ LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
+ arch.GetArchitectureName());
- error = std::static_pointer_cast<NativeProcessNetBSD>(native_process_sp)
- ->LaunchInferior(mainloop, launch_info);
+ std::shared_ptr<NativeProcessNetBSD> process_sp(new NativeProcessNetBSD(
+ pid, launch_info.GetPTY().ReleaseMasterFileDescriptor(), native_delegate,
+ arch, mainloop));
- if (error.Fail()) {
- native_process_sp.reset();
- LLDB_LOG(log, "failed to launch process: {0}", error);
- return error;
- }
+ status = process_sp->ReinitializeThreads();
+ if (status.Fail())
+ return status.ToError();
- launch_info.SetProcessID(native_process_sp->GetID());
+ for (const auto &thread_sp : process_sp->m_threads) {
+ static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
+ SIGSTOP);
+ }
+ process_sp->SetState(StateType::eStateStopped);
- return error;
+ return process_sp;
}
-Status NativeProcessProtocol::Attach(
+llvm::Expected<NativeProcessProtocolSP> NativeProcessNetBSD::Factory::Attach(
lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &native_process_sp) {
+ MainLoop &mainloop) const {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
LLDB_LOG(log, "pid = {0:x}", pid);
// Retrieve the architecture for the running process.
- ArchSpec process_arch;
- Status error = ResolveProcessArchitecture(pid, process_arch);
- if (!error.Success())
- return error;
+ ArchSpec arch;
+ Status status = ResolveProcessArchitecture(pid, arch);
+ if (!status.Success())
+ return status.ToError();
- std::shared_ptr<NativeProcessNetBSD> native_process_netbsd_sp(
- new NativeProcessNetBSD());
+ std::shared_ptr<NativeProcessNetBSD> process_sp(
+ new NativeProcessNetBSD(pid, -1, native_delegate, arch, mainloop));
- if (!native_process_netbsd_sp->RegisterNativeDelegate(native_delegate)) {
- error.SetErrorStringWithFormat("failed to register the native delegate");
- return error;
- }
-
- native_process_netbsd_sp->AttachToInferior(mainloop, pid, error);
- if (!error.Success())
- return error;
+ status = process_sp->Attach();
+ if (!status.Success())
+ return status.ToError();
- native_process_sp = native_process_netbsd_sp;
- return error;
+ return process_sp;
}
// -----------------------------------------------------------------------------
// Public Instance Methods
// -----------------------------------------------------------------------------
-NativeProcessNetBSD::NativeProcessNetBSD()
- : NativeProcessProtocol(LLDB_INVALID_PROCESS_ID), m_arch(),
- m_supports_mem_region(eLazyBoolCalculate), m_mem_region_cache() {}
+NativeProcessNetBSD::NativeProcessNetBSD(::pid_t pid, int terminal_fd,
+ NativeDelegate &delegate,
+ const ArchSpec &arch,
+ MainLoop &mainloop)
+ : NativeProcessProtocol(pid, terminal_fd, delegate), m_arch(arch) {
+ if (m_terminal_fd != -1) {
+ Status status = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
+ assert(status.Success());
+ }
+
+ Status status;
+ m_sigchld_handle = mainloop.RegisterSignal(
+ SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, status);
+ assert(m_sigchld_handle && status.Success());
+}
// Handles all waitpid events from the inferior process.
void NativeProcessNetBSD::MonitorCallback(lldb::pid_t pid, int signal) {
@@ -709,126 +730,17 @@ Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
return Status();
}
-Status NativeProcessNetBSD::LaunchInferior(MainLoop &mainloop,
- ProcessLaunchInfo &launch_info) {
- Status error;
- m_sigchld_handle = mainloop.RegisterSignal(
- SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
- if (!m_sigchld_handle)
- return error;
-
- SetState(eStateLaunching);
-
- ::pid_t pid = ProcessLauncherPosixFork()
- .LaunchProcess(launch_info, error)
- .GetProcessId();
- if (error.Fail())
- return error;
-
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
-
- // Wait for the child process to trap on its call to execve.
- ::pid_t wpid;
- int status;
- if ((wpid = waitpid(pid, &status, 0)) < 0) {
- error.SetErrorToErrno();
- LLDB_LOG(log, "waitpid for inferior failed with %s", error);
-
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For
- // now, using eStateInvalid.
- SetState(StateType::eStateInvalid);
-
- return error;
- }
- assert(WIFSTOPPED(status) && (wpid == static_cast<::pid_t>(pid)) &&
- "Could not sync with inferior process.");
-
- LLDB_LOG(log, "inferior started, now in stopped state");
-
- // Release the master terminal descriptor and pass it off to the
- // NativeProcessNetBSD instance. Similarly stash the inferior pid.
- m_terminal_fd = launch_info.GetPTY().ReleaseMasterFileDescriptor();
- m_pid = pid;
- launch_info.SetProcessID(pid);
-
- if (m_terminal_fd != -1) {
- error = EnsureFDFlags(m_terminal_fd, O_NONBLOCK);
- if (error.Fail()) {
- LLDB_LOG(log,
- "inferior EnsureFDFlags failed for ensuring terminal "
- "O_NONBLOCK setting: {0}",
- error);
-
- // Mark the inferior as invalid.
- // FIXME this could really use a new state - eStateLaunchFailure. For
- // now, using eStateInvalid.
- SetState(StateType::eStateInvalid);
-
- return error;
- }
- }
-
- LLDB_LOG(log, "adding pid = {0}", pid);
-
- ResolveProcessArchitecture(m_pid, m_arch);
-
- error = ReinitializeThreads();
- if (error.Fail()) {
- SetState(StateType::eStateInvalid);
- return error;
- }
-
- for (const auto &thread_sp : m_threads) {
- static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
- SIGSTOP);
- }
-
- /* Set process stopped */
- SetState(StateType::eStateStopped);
-
- if (error.Fail())
- LLDB_LOG(log, "inferior launching failed {0}", error);
- return error;
-}
-
-void NativeProcessNetBSD::AttachToInferior(MainLoop &mainloop, lldb::pid_t pid,
- Status &error) {
- Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
- LLDB_LOG(log, "pid = {0:x}", pid);
-
- m_sigchld_handle = mainloop.RegisterSignal(
- SIGCHLD, [this](MainLoopBase &) { SigchldHandler(); }, error);
- if (!m_sigchld_handle)
- return;
-
- error = ResolveProcessArchitecture(pid, m_arch);
- if (!error.Success())
- return;
-
- // Set the architecture to the exe architecture.
- LLDB_LOG(log, "pid = {0:x}, detected architecture {1}", pid,
- m_arch.GetArchitectureName());
-
- m_pid = pid;
- SetState(eStateAttaching);
-
- Attach(pid, error);
-}
-
void NativeProcessNetBSD::SigchldHandler() {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
// Process all pending waitpid notifications.
int status;
- ::pid_t wait_pid = waitpid(GetID(), &status, WALLSIG | WNOHANG);
+ ::pid_t wait_pid =
+ llvm::sys::RetryAfterSignal(-1, waitpid, GetID(), &status, WALLSIG | WNOHANG);
if (wait_pid == 0)
return; // We are done.
if (wait_pid == -1) {
- if (errno == EINTR)
- return;
-
Status error(errno, eErrorTypePOSIX);
LLDB_LOG(log, "waitpid ({0}, &status, _) failed: {1}", GetID(), error);
}
@@ -880,33 +792,23 @@ NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
return thread_sp;
}
-::pid_t NativeProcessNetBSD::Attach(lldb::pid_t pid, Status &error) {
- if (pid <= 1) {
- error.SetErrorToGenericError();
- error.SetErrorString("Attaching to process 1 is not allowed.");
- return -1;
- }
-
+Status NativeProcessNetBSD::Attach() {
// Attach to the requested process.
// An attach will cause the thread to stop with a SIGSTOP.
- error = PtraceWrapper(PT_ATTACH, pid);
- if (error.Fail())
- return -1;
+ Status status = PtraceWrapper(PT_ATTACH, m_pid);
+ if (status.Fail())
+ return status;
- int status;
+ int wstatus;
// Need to use WALLSIG otherwise we receive an error with errno=ECHLD
// At this point we should have a thread stopped if waitpid succeeds.
- if ((status = waitpid(pid, NULL, WALLSIG)) < 0)
- return -1;
-
- m_pid = pid;
+ if ((wstatus = waitpid(m_pid, NULL, WALLSIG)) < 0)
+ return Status(errno, eErrorTypePOSIX);
/* Initialize threads */
- error = ReinitializeThreads();
- if (error.Fail()) {
- SetState(StateType::eStateInvalid);
- return -1;
- }
+ status = ReinitializeThreads();
+ if (status.Fail())
+ return status;
for (const auto &thread_sp : m_threads) {
static_pointer_cast<NativeThreadNetBSD>(thread_sp)->SetStoppedBySignal(
@@ -915,8 +817,7 @@ NativeThreadNetBSDSP NativeProcessNetBSD::AddThread(lldb::tid_t thread_id) {
// Let our process instance know the thread has stopped.
SetState(StateType::eStateStopped);
-
- return pid;
+ return Status();
}
Status NativeProcessNetBSD::ReadMemory(lldb::addr_t addr, void *buf,
diff --git a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
index 7a1303faea68..34b892f1fc88 100644
--- a/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
+++ b/source/Plugins/Process/NetBSD/NativeProcessNetBSD.h
@@ -31,15 +31,18 @@ namespace process_netbsd {
///
/// Changes in the inferior process state are broadcasted.
class NativeProcessNetBSD : public NativeProcessProtocol {
- friend Status NativeProcessProtocol::Launch(
- ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+public:
+ class Factory : public NativeProcessProtocol::Factory {
+ public:
+ llvm::Expected<NativeProcessProtocolSP>
+ Launch(ProcessLaunchInfo &launch_info, NativeDelegate &native_delegate,
+ MainLoop &mainloop) const override;
- friend Status NativeProcessProtocol::Attach(
- lldb::pid_t pid, NativeProcessProtocol::NativeDelegate &native_delegate,
- MainLoop &mainloop, NativeProcessProtocolSP &process_sp);
+ llvm::Expected<NativeProcessProtocolSP>
+ Attach(lldb::pid_t pid, NativeDelegate &native_delegate,
+ MainLoop &mainloop) const override;
+ };
-public:
// ---------------------------------------------------------------------
// NativeProcessProtocol Interface
// ---------------------------------------------------------------------
@@ -107,21 +110,19 @@ protected:
private:
MainLoop::SignalHandleUP m_sigchld_handle;
ArchSpec m_arch;
- LazyBool m_supports_mem_region;
+ LazyBool m_supports_mem_region = eLazyBoolCalculate;
std::vector<std::pair<MemoryRegionInfo, FileSpec>> m_mem_region_cache;
// ---------------------------------------------------------------------
// Private Instance Methods
// ---------------------------------------------------------------------
- NativeProcessNetBSD();
+ NativeProcessNetBSD(::pid_t pid, int terminal_fd, NativeDelegate &delegate,
+ const ArchSpec &arch, MainLoop &mainloop);
bool HasThreadNoLock(lldb::tid_t thread_id);
NativeThreadNetBSDSP AddThread(lldb::tid_t thread_id);
- Status LaunchInferior(MainLoop &mainloop, ProcessLaunchInfo &launch_info);
- void AttachToInferior(MainLoop &mainloop, lldb::pid_t pid, Status &error);
-
void MonitorCallback(lldb::pid_t pid, int signal);
void MonitorExited(lldb::pid_t pid, WaitStatus status);
void MonitorSIGSTOP(lldb::pid_t pid);
@@ -133,8 +134,7 @@ private:
Status PopulateMemoryRegionCache();
void SigchldHandler();
- ::pid_t Attach(lldb::pid_t pid, Status &error);
-
+ Status Attach();
Status ReinitializeThreads();
};
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
index 3d008f42499d..5e51feef1d3f 100644
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ b/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -7,14 +7,6 @@ set(LLDB_PLUGINS
lldbPluginPlatformMacOSX
)
-if(CMAKE_SYSTEM_NAME MATCHES "Linux|Android")
- list(APPEND LLDB_PLUGINS lldbPluginProcessLinux)
-endif()
-
-if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- list(APPEND LLDB_PLUGINS lldbPluginProcessNetBSD)
-endif()
-
add_lldb_library(lldbPluginProcessGDBRemote PLUGIN
GDBRemoteClientBase.cpp
GDBRemoteCommunication.cpp
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
index 33aed7a43c4a..e6fd386b903b 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
@@ -86,6 +86,7 @@ GDBRemoteCommunicationClient::GDBRemoteCommunicationClient()
m_supports_jLoadedDynamicLibrariesInfos(eLazyBoolCalculate),
m_supports_jGetSharedCacheInfo(eLazyBoolCalculate),
m_supports_QPassSignals(eLazyBoolCalculate),
+ m_supports_error_string_reply(eLazyBoolCalculate),
m_supports_qProcessInfoPID(true), m_supports_qfProcessInfo(true),
m_supports_qUserName(true), m_supports_qGroupName(true),
m_supports_qThreadStopInfo(true), m_supports_z0(true),
@@ -596,6 +597,21 @@ bool GDBRemoteCommunicationClient::GetThreadExtendedInfoSupported() {
return m_supports_jThreadExtendedInfo;
}
+void GDBRemoteCommunicationClient::EnableErrorStringInPacket() {
+ if (m_supports_error_string_reply == eLazyBoolCalculate) {
+ StringExtractorGDBRemote response;
+ // We try to enable error strings in remote packets
+ // but if we fail, we just work in the older way.
+ m_supports_error_string_reply = eLazyBoolNo;
+ if (SendPacketAndWaitForResponse("QEnableErrorStrings", response, false) ==
+ PacketResult::Success) {
+ if (response.IsOKResponse()) {
+ m_supports_error_string_reply = eLazyBoolYes;
+ }
+ }
+ }
+}
+
bool GDBRemoteCommunicationClient::GetLoadedDynamicLibrariesInfosSupported() {
if (m_supports_jLoadedDynamicLibrariesInfos == eLazyBoolCalculate) {
StringExtractorGDBRemote response;
@@ -3181,8 +3197,8 @@ GDBRemoteCommunicationClient::SendStartTracePacket(const TraceOptions &options,
true) ==
GDBRemoteCommunication::PacketResult::Success) {
if (!response.IsNormalResponse()) {
- error.SetError(response.GetError(), eErrorTypeGeneric);
- LLDB_LOG(log, "Target does not support Tracing");
+ error = response.GetStatus();
+ LLDB_LOG(log, "Target does not support Tracing , error {0}", error);
} else {
ret_uid = response.GetHexMaxU64(false, LLDB_INVALID_UID);
}
@@ -3219,7 +3235,7 @@ GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
true) ==
GDBRemoteCommunication::PacketResult::Success) {
if (!response.IsOKResponse()) {
- error.SetError(response.GetError(), eErrorTypeGeneric);
+ error = response.GetStatus();
LLDB_LOG(log, "stop tracing failed");
}
} else {
@@ -3234,6 +3250,7 @@ GDBRemoteCommunicationClient::SendStopTracePacket(lldb::user_id_t uid,
Status GDBRemoteCommunicationClient::SendGetDataPacket(
lldb::user_id_t uid, lldb::tid_t thread_id,
llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
+
StreamGDBRemote escaped_packet;
escaped_packet.PutCString("jTraceBufferRead:");
return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
@@ -3242,6 +3259,7 @@ Status GDBRemoteCommunicationClient::SendGetDataPacket(
Status GDBRemoteCommunicationClient::SendGetMetaDataPacket(
lldb::user_id_t uid, lldb::tid_t thread_id,
llvm::MutableArrayRef<uint8_t> &buffer, size_t offset) {
+
StreamGDBRemote escaped_packet;
escaped_packet.PutCString("jTraceMetaRead:");
return SendGetTraceDataPacket(escaped_packet, uid, thread_id, buffer, offset);
@@ -3308,7 +3326,7 @@ GDBRemoteCommunicationClient::SendGetTraceConfigPacket(lldb::user_id_t uid,
custom_params_sp));
}
} else {
- error.SetError(response.GetError(), eErrorTypeGeneric);
+ error = response.GetStatus();
}
} else {
LLDB_LOG(log, "failed to send packet");
@@ -3344,7 +3362,7 @@ Status GDBRemoteCommunicationClient::SendGetTraceDataPacket(
size_t filled_size = response.GetHexBytesAvail(buffer);
buffer = llvm::MutableArrayRef<uint8_t>(buffer.data(), filled_size);
} else {
- error.SetError(response.GetError(), eErrorTypeGeneric);
+ error = response.GetStatus();
buffer = buffer.slice(buffer.size());
}
} else {
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
index a38110faaec6..712d85eed082 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
@@ -340,6 +340,8 @@ public:
bool GetQXferAuxvReadSupported();
+ void EnableErrorStringInPacket();
+
bool GetQXferLibrariesReadSupported();
bool GetQXferLibrariesSVR4ReadSupported();
@@ -549,6 +551,7 @@ protected:
LazyBool m_supports_jLoadedDynamicLibrariesInfos;
LazyBool m_supports_jGetSharedCacheInfo;
LazyBool m_supports_QPassSignals;
+ LazyBool m_supports_error_string_reply;
bool m_supports_qProcessInfoPID : 1, m_supports_qfProcessInfo : 1,
m_supports_qUserName : 1, m_supports_qGroupName : 1,
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
index dac675ee9432..4be92b79fd1a 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.cpp
@@ -20,6 +20,7 @@
// Project includes
#include "ProcessGDBRemoteLog.h"
#include "Utility/StringExtractorGDBRemote.h"
+#include "lldb/Utility/StreamString.h"
using namespace lldb;
using namespace lldb_private;
@@ -27,7 +28,12 @@ using namespace lldb_private::process_gdb_remote;
GDBRemoteCommunicationServer::GDBRemoteCommunicationServer(
const char *comm_name, const char *listener_name)
- : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {}
+ : GDBRemoteCommunication(comm_name, listener_name), m_exit_now(false) {
+ RegisterPacketHandler(
+ StringExtractorGDBRemote::eServerPacketType_QEnableErrorStrings,
+ [this](StringExtractorGDBRemote packet, Status &error, bool &interrupt,
+ bool &quit) { return this->Handle_QErrorStringEnable(packet); });
+}
GDBRemoteCommunicationServer::~GDBRemoteCommunicationServer() {}
@@ -100,6 +106,24 @@ GDBRemoteCommunicationServer::SendErrorResponse(uint8_t err) {
}
GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::SendErrorResponse(const Status &error) {
+ if (m_send_error_strings) {
+ lldb_private::StreamString packet;
+ packet.Printf("E%2.2x;", static_cast<uint8_t>(error.GetError()));
+ packet.PutCStringAsRawHex8(error.AsCString());
+ return SendPacketNoLock(packet.GetString());
+ } else
+ return SendErrorResponse(error.GetError());
+}
+
+GDBRemoteCommunication::PacketResult
+GDBRemoteCommunicationServer::Handle_QErrorStringEnable(
+ StringExtractorGDBRemote &packet) {
+ m_send_error_strings = true;
+ return SendOKResponse();
+}
+
+GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::SendIllFormedResponse(
const StringExtractorGDBRemote &failed_packet, const char *message) {
Log *log(ProcessGDBRemoteLog::GetLogIfAllCategoriesSet(GDBR_LOG_PACKETS));
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
index 6eb25f8b9f98..a35352480040 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServer.h
@@ -57,6 +57,13 @@ protected:
bool m_exit_now; // use in asynchronous handling to indicate process should
// exit.
+ bool m_send_error_strings; // If the client enables this then
+ // we will send error strings as well.
+
+ PacketResult Handle_QErrorStringEnable(StringExtractorGDBRemote &packet);
+
+ PacketResult SendErrorResponse(const Status &error);
+
PacketResult SendUnimplementedResponse(const char *packet);
PacketResult SendErrorResponse(uint8_t error);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
index de2400c51ba3..f53db502be93 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerCommon.cpp
@@ -1046,14 +1046,9 @@ GDBRemoteCommunicationServerCommon::Handle_A(StringExtractorGDBRemote &packet) {
if (success) {
m_process_launch_error = LaunchProcess();
- if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) {
+ if (m_process_launch_error.Success())
return SendOKResponse();
- } else {
- Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
- if (log)
- log->Printf("LLGSPacketHandler::%s failed to launch exe: %s",
- __FUNCTION__, m_process_launch_error.AsCString());
- }
+ LLDB_LOG(log, "failed to launch exe: {0}", m_process_launch_error);
}
return SendErrorResponse(8);
}
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
index 7523260c13e4..a7fe4ee3b147 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.cpp
@@ -73,15 +73,11 @@ enum GDBRemoteServerError {
// GDBRemoteCommunicationServerLLGS constructor
//----------------------------------------------------------------------
GDBRemoteCommunicationServerLLGS::GDBRemoteCommunicationServerLLGS(
- MainLoop &mainloop)
+ MainLoop &mainloop, const NativeProcessProtocol::Factory &process_factory)
: GDBRemoteCommunicationServerCommon("gdb-remote.server",
"gdb-remote.server.rx_packet"),
- m_mainloop(mainloop), m_current_tid(LLDB_INVALID_THREAD_ID),
- m_continue_tid(LLDB_INVALID_THREAD_ID), m_debugged_process_mutex(),
- m_debugged_process_sp(), m_stdio_communication("process.stdio"),
- m_inferior_prev_state(StateType::eStateInvalid),
- m_saved_registers_map(), m_next_saved_registers_id(1),
- m_handshake_completed(false) {
+ m_mainloop(mainloop), m_process_factory(process_factory),
+ m_stdio_communication("process.stdio") {
RegisterPacketHandlers();
}
@@ -241,19 +237,20 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
const bool default_to_use_pty = true;
m_process_launch_info.FinalizeFileActions(nullptr, default_to_use_pty);
- Status error;
{
std::lock_guard<std::recursive_mutex> guard(m_debugged_process_mutex);
assert(!m_debugged_process_sp && "lldb-server creating debugged "
"process but one already exists");
- error = NativeProcessProtocol::Launch(m_process_launch_info, *this,
- m_mainloop, m_debugged_process_sp);
- }
-
- if (!error.Success()) {
- fprintf(stderr, "%s: failed to launch executable %s", __FUNCTION__,
- m_process_launch_info.GetArguments().GetArgumentAtIndex(0));
- return error;
+ auto process_or =
+ m_process_factory.Launch(m_process_launch_info, *this, m_mainloop);
+ if (!process_or) {
+ Status status(process_or.takeError());
+ llvm::errs() << llvm::formatv(
+ "failed to launch executable `{0}`: {1}",
+ m_process_launch_info.GetArguments().GetArgumentAtIndex(0), status);
+ return status;
+ }
+ m_debugged_process_sp = *process_or;
}
// Handle mirroring of inferior stdout/stderr over the gdb-remote protocol
@@ -279,9 +276,9 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
"inferior STDIO fd to %d",
__FUNCTION__, terminal_fd);
- error = SetSTDIOFileDescriptor(terminal_fd);
- if (error.Fail())
- return error;
+ Status status = SetSTDIOFileDescriptor(terminal_fd);
+ if (status.Fail())
+ return status;
} else {
if (log)
log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
@@ -298,14 +295,12 @@ Status GDBRemoteCommunicationServerLLGS::LaunchProcess() {
printf("Launched '%s' as process %" PRIu64 "...\n",
m_process_launch_info.GetArguments().GetArgumentAtIndex(0),
- m_process_launch_info.GetProcessID());
+ m_debugged_process_sp->GetID());
- return error;
+ return Status();
}
Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
- Status error;
-
Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS));
if (log)
log->Printf("GDBRemoteCommunicationServerLLGS::%s pid %" PRIu64,
@@ -321,13 +316,14 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
pid, m_debugged_process_sp->GetID());
// Try to attach.
- error = NativeProcessProtocol::Attach(pid, *this, m_mainloop,
- m_debugged_process_sp);
- if (!error.Success()) {
- fprintf(stderr, "%s: failed to attach to process %" PRIu64 ": %s",
- __FUNCTION__, pid, error.AsCString());
- return error;
+ auto process_or = m_process_factory.Attach(pid, *this, m_mainloop);
+ if (!process_or) {
+ Status status(process_or.takeError());
+ llvm::errs() << llvm::formatv("failed to attach to process {0}: {1}", pid,
+ status);
+ return status;
}
+ m_debugged_process_sp = *process_or;
// Setup stdout/stderr mapping from inferior.
auto terminal_fd = m_debugged_process_sp->GetTerminalFileDescriptor();
@@ -336,9 +332,9 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s setting "
"inferior STDIO fd to %d",
__FUNCTION__, terminal_fd);
- error = SetSTDIOFileDescriptor(terminal_fd);
- if (error.Fail())
- return error;
+ Status status = SetSTDIOFileDescriptor(terminal_fd);
+ if (status.Fail())
+ return status;
} else {
if (log)
log->Printf("ProcessGDBRemoteCommunicationServerLLGS::%s ignoring "
@@ -347,8 +343,7 @@ Status GDBRemoteCommunicationServerLLGS::AttachToProcess(lldb::pid_t pid) {
}
printf("Attached to process %" PRIu64 "...\n", pid);
-
- return error;
+ return Status();
}
void GDBRemoteCommunicationServerLLGS::InitializeDelegate(
@@ -1128,7 +1123,7 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStart(
uid = m_debugged_process_sp->StartTrace(options, error);
LLDB_LOG(log, "uid is {0} , error is {1}", uid, error.GetError());
if (error.Fail())
- return SendErrorResponse(error.GetError());
+ return SendErrorResponse(error);
StreamGDBRemote response;
response.Printf("%" PRIx64, uid);
@@ -1165,7 +1160,7 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceStop(
Status error = m_debugged_process_sp->StopTrace(uid, tid);
if (error.Fail())
- return SendErrorResponse(error.GetError());
+ return SendErrorResponse(error);
return SendOKResponse();
}
@@ -1208,7 +1203,7 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceConfigRead(
Status error = m_debugged_process_sp->GetTraceConfig(uid, options);
if (error.Fail())
- return SendErrorResponse(error.GetError());
+ return SendErrorResponse(error);
StreamGDBRemote escaped_response;
StructuredData::Dictionary json_packet;
@@ -1284,7 +1279,7 @@ GDBRemoteCommunicationServerLLGS::Handle_jTraceRead(
error = m_debugged_process_sp->GetMetaData(uid, tid, buf, offset);
if (error.Fail())
- return SendErrorResponse(error.GetError());
+ return SendErrorResponse(error);
for (auto i : buf)
response.PutHex8(i);
diff --git a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
index a7d7850d454f..b065642d4aed 100644
--- a/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
+++ b/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationServerLLGS.h
@@ -39,7 +39,9 @@ public:
//------------------------------------------------------------------
// Constructors and Destructors
//------------------------------------------------------------------
- GDBRemoteCommunicationServerLLGS(MainLoop &mainloop);
+ GDBRemoteCommunicationServerLLGS(
+ MainLoop &mainloop,
+ const NativeProcessProtocol::Factory &process_factory);
//------------------------------------------------------------------
/// Specify the program to launch and its arguments.
@@ -108,20 +110,21 @@ public:
protected:
MainLoop &m_mainloop;
MainLoop::ReadHandleUP m_network_handle_up;
- lldb::tid_t m_current_tid;
- lldb::tid_t m_continue_tid;
+ const NativeProcessProtocol::Factory &m_process_factory;
+ lldb::tid_t m_current_tid = LLDB_INVALID_THREAD_ID;
+ lldb::tid_t m_continue_tid = LLDB_INVALID_THREAD_ID;
std::recursive_mutex m_debugged_process_mutex;
NativeProcessProtocolSP m_debugged_process_sp;
Communication m_stdio_communication;
MainLoop::ReadHandleUP m_stdio_handle_up;
- lldb::StateType m_inferior_prev_state;
+ lldb::StateType m_inferior_prev_state = lldb::StateType::eStateInvalid;
std::unique_ptr<llvm::MemoryBuffer> m_active_auxv_buffer_up;
std::mutex m_saved_registers_mutex;
std::unordered_map<uint32_t, lldb::DataBufferSP> m_saved_registers_map;
- uint32_t m_next_saved_registers_id;
- bool m_handshake_completed : 1;
+ uint32_t m_next_saved_registers_id = 1;
+ bool m_handshake_completed = false;
PacketResult SendONotification(const char *buffer, uint32_t len);
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 042c96111bb3..8a66f3865ebc 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1031,6 +1031,7 @@ Status ProcessGDBRemote::ConnectToDebugserver(llvm::StringRef connect_url) {
m_gdb_comm.GetHostInfo();
m_gdb_comm.GetVContSupported('c');
m_gdb_comm.GetVAttachOrWaitSupported();
+ m_gdb_comm.EnableErrorStringInPacket();
// Ask the remote server for the default thread id
if (GetTarget().GetNonStopModeEnabled())
diff --git a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
index b7fbd7347d08..6c39690268c6 100644
--- a/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
+++ b/source/Plugins/ScriptInterpreter/Python/ScriptInterpreterPython.cpp
@@ -1857,14 +1857,12 @@ StructuredData::DictionarySP ScriptInterpreterPython::GetDynamicSettings(
return StructuredData::DictionarySP();
PythonObject reply_pyobj;
- {
- Locker py_lock(this,
- Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
- TargetSP target_sp(target->shared_from_this());
- reply_pyobj.Reset(PyRefType::Owned,
- (PyObject *)g_swig_plugin_get(generic->GetValue(),
- setting_name, target_sp));
- }
+ Locker py_lock(this,
+ Locker::AcquireLock | Locker::InitSession | Locker::NoSTDIN);
+ TargetSP target_sp(target->shared_from_this());
+ reply_pyobj.Reset(PyRefType::Owned,
+ (PyObject *)g_swig_plugin_get(generic->GetValue(),
+ setting_name, target_sp));
PythonDictionary py_dict(PyRefType::Borrowed, reply_pyobj.get());
return py_dict.CreateStructuredDictionary();
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
index 9d79a411faad..aa15063ac0dc 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.cpp
@@ -604,9 +604,10 @@ uint32_t x86AssemblyInspectionEngine::extract_4(uint8_t *b) {
}
bool x86AssemblyInspectionEngine::instruction_length(uint8_t *insn_p,
- int &length) {
+ int &length,
+ uint32_t buffer_remaining_bytes) {
- const uint32_t max_op_byte_size = m_arch.GetMaximumOpcodeByteSize();
+ uint32_t max_op_byte_size = std::min(buffer_remaining_bytes, m_arch.GetMaximumOpcodeByteSize());
llvm::SmallVector<uint8_t, 32> opcode_data;
opcode_data.resize(max_op_byte_size);
@@ -698,8 +699,9 @@ bool x86AssemblyInspectionEngine::GetNonCallSiteUnwindPlanFromAssembly(
bool row_updated = false; // The UnwindPlan::Row 'row' has been updated
m_cur_insn = data + current_func_text_offset;
- if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
- insn_len > kMaxInstructionByteSize) {
+ if (!instruction_length(m_cur_insn, insn_len, size - current_func_text_offset)
+ || insn_len == 0
+ || insn_len > kMaxInstructionByteSize) {
// An unrecognized/junk instruction
break;
}
@@ -1002,8 +1004,9 @@ bool x86AssemblyInspectionEngine::AugmentUnwindPlanFromCallSite(
while (offset < size) {
m_cur_insn = data + offset;
int insn_len;
- if (!instruction_length(m_cur_insn, insn_len) || insn_len == 0 ||
- insn_len > kMaxInstructionByteSize) {
+ if (!instruction_length(m_cur_insn, insn_len, size - offset)
+ || insn_len == 0
+ || insn_len > kMaxInstructionByteSize) {
// An unrecognized/junk instruction.
break;
}
@@ -1214,8 +1217,9 @@ bool x86AssemblyInspectionEngine::FindFirstNonPrologueInstruction(
int scratch;
m_cur_insn = data + offset;
- if (!instruction_length(m_cur_insn, insn_len) ||
- insn_len > kMaxInstructionByteSize || insn_len == 0) {
+ if (!instruction_length(m_cur_insn, insn_len, size - offset)
+ || insn_len > kMaxInstructionByteSize
+ || insn_len == 0) {
// An error parsing the instruction, i.e. probably data/garbage - stop
// scanning
break;
diff --git a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
index 2e7875966cb6..97441d362973 100644
--- a/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
+++ b/source/Plugins/UnwindAssembly/x86/x86AssemblyInspectionEngine.h
@@ -113,7 +113,7 @@ private:
bool ret_pattern_p();
uint32_t extract_4(uint8_t *b);
- bool instruction_length(uint8_t *insn, int &length);
+ bool instruction_length(uint8_t *insn, int &length, uint32_t buffer_remaining_bytes);
bool machine_regno_to_lldb_regno(int machine_regno, uint32_t &lldb_regno);
diff --git a/source/Utility/StringExtractorGDBRemote.cpp b/source/Utility/StringExtractorGDBRemote.cpp
index 3473a9e96689..8e50c0106a48 100644
--- a/source/Utility/StringExtractorGDBRemote.cpp
+++ b/source/Utility/StringExtractorGDBRemote.cpp
@@ -19,8 +19,18 @@ StringExtractorGDBRemote::GetResponseType() const {
switch (m_packet[0]) {
case 'E':
- if (m_packet.size() == 3 && isxdigit(m_packet[1]) && isxdigit(m_packet[2]))
- return eError;
+ if (isxdigit(m_packet[1]) && isxdigit(m_packet[2])) {
+ if (m_packet.size() == 3)
+ return eError;
+ llvm::StringRef packet_ref(m_packet);
+ if (packet_ref[3] == ';') {
+ auto err_string = packet_ref.substr(4);
+ for (auto e : err_string)
+ if (!isxdigit(e))
+ return eResponse;
+ return eError;
+ }
+ }
break;
case 'O':
@@ -86,6 +96,8 @@ StringExtractorGDBRemote::GetServerPacketType() const {
return eServerPacketType_QEnvironment;
if (PACKET_STARTS_WITH("QEnvironmentHexEncoded:"))
return eServerPacketType_QEnvironmentHexEncoded;
+ if (PACKET_STARTS_WITH("QEnableErrorStrings"))
+ return eServerPacketType_QEnableErrorStrings;
break;
case 'P':
@@ -438,8 +450,8 @@ bool StringExtractorGDBRemote::IsNormalResponse() const {
}
bool StringExtractorGDBRemote::IsErrorResponse() const {
- return GetResponseType() == eError && m_packet.size() == 3 &&
- isxdigit(m_packet[1]) && isxdigit(m_packet[2]);
+ return GetResponseType() == eError && isxdigit(m_packet[1]) &&
+ isxdigit(m_packet[2]);
}
uint8_t StringExtractorGDBRemote::GetError() {
@@ -450,6 +462,23 @@ uint8_t StringExtractorGDBRemote::GetError() {
return 0;
}
+lldb_private::Status StringExtractorGDBRemote::GetStatus() {
+ lldb_private::Status error;
+ if (GetResponseType() == eError) {
+ SetFilePos(1);
+ uint8_t errc = GetHexU8(255);
+ error.SetError(errc, lldb::eErrorTypeGeneric);
+
+ error.SetErrorStringWithFormat("Error %u", errc);
+ std::string error_messg;
+ if (GetChar() == ';') {
+ GetHexByteString(error_messg);
+ error.SetErrorString(error_messg);
+ }
+ }
+ return error;
+}
+
size_t StringExtractorGDBRemote::GetEscapedBinaryData(std::string &str) {
// Just get the data bytes in the string as
// GDBRemoteCommunication::CheckForPacket()
diff --git a/source/Utility/StringExtractorGDBRemote.h b/source/Utility/StringExtractorGDBRemote.h
index 473cab04f800..f4ed642a706e 100644
--- a/source/Utility/StringExtractorGDBRemote.h
+++ b/source/Utility/StringExtractorGDBRemote.h
@@ -10,6 +10,7 @@
#ifndef utility_StringExtractorGDBRemote_h_
#define utility_StringExtractorGDBRemote_h_
+#include "lldb/Utility/Status.h"
#include "lldb/Utility/StringExtractor.h"
#include "llvm/ADT/StringRef.h" // for StringRef
@@ -72,6 +73,7 @@ public:
eServerPacketType_qGetWorkingDir,
eServerPacketType_qFileLoadAddress,
eServerPacketType_QEnvironment,
+ eServerPacketType_QEnableErrorStrings,
eServerPacketType_QLaunchArch,
eServerPacketType_QSetDisableASLR,
eServerPacketType_QSetDetachOnError,
@@ -190,6 +192,8 @@ public:
// digits. Otherwise the error encoded in XX is returned.
uint8_t GetError();
+ lldb_private::Status GetStatus();
+
size_t GetEscapedBinaryData(std::string &str);
protected: