aboutsummaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
Diffstat (limited to 'source')
-rw-r--r--source/API/SBAddress.cpp6
-rw-r--r--source/API/SBInstruction.cpp7
-rw-r--r--source/API/SBInstructionList.cpp26
-rw-r--r--source/API/SBProcess.cpp16
-rw-r--r--source/Core/Disassembler.cpp4
-rw-r--r--source/Host/common/Editline.cpp2
-rw-r--r--source/Host/common/MainLoop.cpp206
-rw-r--r--source/Host/common/UDPSocket.cpp82
-rw-r--r--source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp34
-rw-r--r--source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp17
-rw-r--r--source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp73
-rw-r--r--source/Target/ThreadPlanCallUserExpression.cpp11
-rw-r--r--source/Utility/TaskPool.cpp23
13 files changed, 282 insertions, 225 deletions
diff --git a/source/API/SBAddress.cpp b/source/API/SBAddress.cpp
index b452ce327ab7..a3493d7c743f 100644
--- a/source/API/SBAddress.cpp
+++ b/source/API/SBAddress.cpp
@@ -55,6 +55,12 @@ const SBAddress &SBAddress::operator=(const SBAddress &rhs) {
return *this;
}
+bool lldb::operator==(const SBAddress &lhs, const SBAddress &rhs) {
+ if (lhs.IsValid() && rhs.IsValid())
+ return lhs.ref() == rhs.ref();
+ return false;
+}
+
bool SBAddress::IsValid() const {
return m_opaque_ap.get() != NULL && m_opaque_ap->IsValid();
}
diff --git a/source/API/SBInstruction.cpp b/source/API/SBInstruction.cpp
index c47307c733a8..8b7deb7011be 100644
--- a/source/API/SBInstruction.cpp
+++ b/source/API/SBInstruction.cpp
@@ -176,6 +176,13 @@ bool SBInstruction::HasDelaySlot() {
return false;
}
+bool SBInstruction::CanSetBreakpoint () {
+ lldb::InstructionSP inst_sp(GetOpaque());
+ if (inst_sp)
+ return inst_sp->CanSetBreakpoint();
+ return false;
+}
+
lldb::InstructionSP SBInstruction::GetOpaque() {
if (m_opaque_sp)
return m_opaque_sp->GetSP();
diff --git a/source/API/SBInstructionList.cpp b/source/API/SBInstructionList.cpp
index 04c37f50c2d7..3edb9eae98c1 100644
--- a/source/API/SBInstructionList.cpp
+++ b/source/API/SBInstructionList.cpp
@@ -9,6 +9,7 @@
#include "lldb/API/SBInstructionList.h"
#include "lldb/API/SBInstruction.h"
+#include "lldb/API/SBAddress.h"
#include "lldb/API/SBStream.h"
#include "lldb/Core/Disassembler.h"
#include "lldb/Core/Module.h"
@@ -49,6 +50,31 @@ SBInstruction SBInstructionList::GetInstructionAtIndex(uint32_t idx) {
return inst;
}
+size_t SBInstructionList::GetInstructionsCount(const SBAddress &start,
+ const SBAddress &end,
+ bool canSetBreakpoint) {
+ size_t num_instructions = GetSize();
+ size_t i = 0;
+ SBAddress addr;
+ size_t lower_index = 0;
+ size_t upper_index = 0;
+ size_t instructions_to_skip = 0;
+ for (i = 0; i < num_instructions; ++i) {
+ addr = GetInstructionAtIndex(i).GetAddress();
+ if (start == addr)
+ lower_index = i;
+ if (end == addr)
+ upper_index = i;
+ }
+ if (canSetBreakpoint)
+ for (i = lower_index; i <= upper_index; ++i) {
+ SBInstruction insn = GetInstructionAtIndex(i);
+ if (!insn.CanSetBreakpoint())
+ ++instructions_to_skip;
+ }
+ return upper_index - lower_index - instructions_to_skip;
+}
+
void SBInstructionList::Clear() { m_opaque_sp.reset(); }
void SBInstructionList::AppendInstruction(SBInstruction insn) {}
diff --git a/source/API/SBProcess.cpp b/source/API/SBProcess.cpp
index 5614cb468a69..0348113a9873 100644
--- a/source/API/SBProcess.cpp
+++ b/source/API/SBProcess.cpp
@@ -1157,22 +1157,34 @@ uint32_t SBProcess::LoadImage(lldb::SBFileSpec &sb_remote_image_spec,
uint32_t SBProcess::LoadImage(const lldb::SBFileSpec &sb_local_image_spec,
const lldb::SBFileSpec &sb_remote_image_spec,
lldb::SBError &sb_error) {
+ Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
ProcessSP process_sp(GetSP());
if (process_sp) {
Process::StopLocker stop_locker;
if (stop_locker.TryLock(&process_sp->GetRunLock())) {
+ if (log)
+ log->Printf("SBProcess(%p)::LoadImage() => calling Platform::LoadImage"
+ "for: %s",
+ static_cast<void *>(process_sp.get()),
+ sb_local_image_spec.GetFilename());
+
std::lock_guard<std::recursive_mutex> guard(
- process_sp->GetTarget().GetAPIMutex());
+ process_sp->GetTarget().GetAPIMutex());
PlatformSP platform_sp = process_sp->GetTarget().GetPlatform();
return platform_sp->LoadImage(process_sp.get(), *sb_local_image_spec,
*sb_remote_image_spec, sb_error.ref());
} else {
- Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
if (log)
log->Printf("SBProcess(%p)::LoadImage() => error: process is running",
static_cast<void *>(process_sp.get()));
sb_error.SetErrorString("process is running");
}
+ } else {
+ if (log)
+ log->Printf("SBProcess(%p)::LoadImage() => error: called with invalid"
+ " process",
+ static_cast<void *>(process_sp.get()));
+ sb_error.SetErrorString("process is invalid");
}
return LLDB_INVALID_IMAGE_TOKEN;
}
diff --git a/source/Core/Disassembler.cpp b/source/Core/Disassembler.cpp
index 3880bfd16ecc..51d93d9acdbb 100644
--- a/source/Core/Disassembler.cpp
+++ b/source/Core/Disassembler.cpp
@@ -759,6 +759,10 @@ bool Instruction::DumpEmulation(const ArchSpec &arch) {
return false;
}
+bool Instruction::CanSetBreakpoint () {
+ return !HasDelaySlot();
+}
+
bool Instruction::HasDelaySlot() {
// Default is false.
return false;
diff --git a/source/Host/common/Editline.cpp b/source/Host/common/Editline.cpp
index b157cdb7c110..851287e76331 100644
--- a/source/Host/common/Editline.cpp
+++ b/source/Host/common/Editline.cpp
@@ -367,7 +367,7 @@ void Editline::MoveCursor(CursorLocation from, CursorLocation to) {
if (to == CursorLocation::EditingCursor) {
toColumn =
editline_cursor_position - (editline_cursor_row * m_terminal_width) + 1;
- } else if (to == CursorLocation::BlockEnd) {
+ } else if (to == CursorLocation::BlockEnd && !m_input_lines.empty()) {
toColumn =
((m_input_lines[m_input_lines.size() - 1].length() + GetPromptWidth()) %
80) +
diff --git a/source/Host/common/MainLoop.cpp b/source/Host/common/MainLoop.cpp
index 8a9d4f020d5f..abd52f7f46fb 100644
--- a/source/Host/common/MainLoop.cpp
+++ b/source/Host/common/MainLoop.cpp
@@ -18,6 +18,11 @@
#include <vector>
#include <time.h>
+// Multiplexing is implemented using kqueue on systems that support it (BSD
+// variants including OSX). On linux we use ppoll, while android uses pselect
+// (ppoll is present but not implemented properly). On windows we use WSApoll
+// (which does not support signals).
+
#if HAVE_SYS_EVENT_H
#include <sys/event.h>
#elif defined(LLVM_ON_WIN32)
@@ -65,92 +70,72 @@ static void SignalHandler(int signo, siginfo_t *info, void *) {
class MainLoop::RunImpl {
public:
- // TODO: Use llvm::Expected<T>
- static std::unique_ptr<RunImpl> Create(MainLoop &loop, Error &error);
- ~RunImpl();
+ RunImpl(MainLoop &loop);
+ ~RunImpl() = default;
Error Poll();
-
- template <typename F> void ForEachReadFD(F &&f);
- template <typename F> void ForEachSignal(F &&f);
+ void ProcessEvents();
private:
MainLoop &loop;
#if HAVE_SYS_EVENT_H
- int queue_id;
std::vector<struct kevent> in_events;
struct kevent out_events[4];
int num_events = -1;
- RunImpl(MainLoop &loop, int queue_id) : loop(loop), queue_id(queue_id) {
- in_events.reserve(loop.m_read_fds.size() + loop.m_signals.size());
- }
#else
- std::vector<int> signals;
#ifdef FORCE_PSELECT
fd_set read_fd_set;
#else
std::vector<struct pollfd> read_fds;
#endif
- RunImpl(MainLoop &loop) : loop(loop) {
- signals.reserve(loop.m_signals.size());
- }
-
sigset_t get_sigmask();
#endif
};
#if HAVE_SYS_EVENT_H
-MainLoop::RunImpl::~RunImpl() {
- int r = close(queue_id);
- assert(r == 0);
- (void)r;
-}
-std::unique_ptr<MainLoop::RunImpl> MainLoop::RunImpl::Create(MainLoop &loop, Error &error)
-{
- error.Clear();
- int queue_id = kqueue();
- if(queue_id < 0) {
- error = Error(errno, eErrorTypePOSIX);
- return nullptr;
- }
- return std::unique_ptr<RunImpl>(new RunImpl(loop, queue_id));
+MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) {
+ in_events.reserve(loop.m_read_fds.size());
}
Error MainLoop::RunImpl::Poll() {
- in_events.resize(loop.m_read_fds.size() + loop.m_signals.size());
+ in_events.resize(loop.m_read_fds.size());
unsigned i = 0;
for (auto &fd : loop.m_read_fds)
EV_SET(&in_events[i++], fd.first, EVFILT_READ, EV_ADD, 0, 0, 0);
- for (const auto &sig : loop.m_signals)
- EV_SET(&in_events[i++], sig.first, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
-
- num_events = kevent(queue_id, in_events.data(), in_events.size(), out_events,
- llvm::array_lengthof(out_events), nullptr);
+ num_events = kevent(loop.m_kqueue, in_events.data(), in_events.size(),
+ out_events, llvm::array_lengthof(out_events), nullptr);
if (num_events < 0)
return Error("kevent() failed with error %d\n", num_events);
return Error();
}
-template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
+void MainLoop::RunImpl::ProcessEvents() {
assert(num_events >= 0);
for (int i = 0; i < num_events; ++i) {
- f(out_events[i].ident);
if (loop.m_terminate_request)
return;
+ switch (out_events[i].filter) {
+ case EVFILT_READ:
+ loop.ProcessReadObject(out_events[i].ident);
+ break;
+ case EVFILT_SIGNAL:
+ loop.ProcessSignal(out_events[i].ident);
+ break;
+ default:
+ llvm_unreachable("Unknown event");
+ }
}
}
-template <typename F> void MainLoop::RunImpl::ForEachSignal(F && f) {}
#else
-MainLoop::RunImpl::~RunImpl() {}
-std::unique_ptr<MainLoop::RunImpl> MainLoop::RunImpl::Create(MainLoop &loop, Error &error)
-{
- error.Clear();
- return std::unique_ptr<RunImpl>(new RunImpl(loop));
+MainLoop::RunImpl::RunImpl(MainLoop &loop) : loop(loop) {
+#ifndef FORCE_PSELECT
+ read_fds.reserve(loop.m_read_fds.size());
+#endif
}
sigset_t MainLoop::RunImpl::get_sigmask() {
@@ -162,18 +147,14 @@ sigset_t MainLoop::RunImpl::get_sigmask() {
assert(ret == 0);
(void) ret;
- for (const auto &sig : loop.m_signals) {
- signals.push_back(sig.first);
+ for (const auto &sig : loop.m_signals)
sigdelset(&sigmask, sig.first);
- }
return sigmask;
#endif
}
#ifdef FORCE_PSELECT
Error MainLoop::RunImpl::Poll() {
- signals.clear();
-
FD_ZERO(&read_fd_set);
int nfds = 0;
for (const auto &fd : loop.m_read_fds) {
@@ -188,20 +169,8 @@ Error MainLoop::RunImpl::Poll() {
return Error();
}
-
-template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
- for (const auto &fd : loop.m_read_fds) {
- if(!FD_ISSET(fd.first, &read_fd_set))
- continue;
-
- f(fd.first);
- if (loop.m_terminate_request)
- return;
- }
-}
#else
Error MainLoop::RunImpl::Poll() {
- signals.clear();
read_fds.clear();
sigset_t sigmask = get_sigmask();
@@ -220,33 +189,47 @@ Error MainLoop::RunImpl::Poll() {
return Error();
}
+#endif
-template <typename F> void MainLoop::RunImpl::ForEachReadFD(F &&f) {
+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;
+#else
for (const auto &fd : read_fds) {
if ((fd.revents & POLLIN) == 0)
continue;
-
- f(fd.fd);
+ IOObject::WaitableHandle handle = fd.fd;
+#endif
if (loop.m_terminate_request)
return;
- }
-}
-#endif
-template <typename F> void MainLoop::RunImpl::ForEachSignal(F &&f) {
- for (int sig : signals) {
- if (g_signal_flags[sig] == 0)
- continue; // No signal
- g_signal_flags[sig] = 0;
- f(sig);
+ loop.ProcessReadObject(handle);
+ }
+ for (const auto &entry : loop.m_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);
}
}
#endif
+MainLoop::MainLoop() {
+#if HAVE_SYS_EVENT_H
+ m_kqueue = kqueue();
+ assert(m_kqueue >= 0);
+#endif
+}
MainLoop::~MainLoop() {
+#if HAVE_SYS_EVENT_H
+ close(m_kqueue);
+#endif
assert(m_read_fds.size() == 0);
assert(m_signals.size() == 0);
}
@@ -298,24 +281,30 @@ MainLoop::RegisterSignal(int signo, const Callback &callback,
new_action.sa_flags = SA_SIGINFO;
sigemptyset(&new_action.sa_mask);
sigaddset(&new_action.sa_mask, signo);
-
sigset_t old_set;
- if (int ret = pthread_sigmask(SIG_BLOCK, &new_action.sa_mask, &old_set)) {
- error.SetErrorStringWithFormat("pthread_sigmask failed with error %d\n",
- ret);
- return nullptr;
- }
- info.was_blocked = sigismember(&old_set, signo);
- if (sigaction(signo, &new_action, &info.old_action) == -1) {
- error.SetErrorToErrno();
- if (!info.was_blocked)
- pthread_sigmask(SIG_UNBLOCK, &new_action.sa_mask, nullptr);
- return nullptr;
- }
+ g_signal_flags[signo] = 0;
+
+ // Even if using kqueue, the signal handler will still be invoked, so it's
+ // important to replace it with our "bening" handler.
+ int ret = sigaction(signo, &new_action, &info.old_action);
+ assert(ret == 0 && "sigaction failed");
+#if HAVE_SYS_EVENT_H
+ struct kevent ev;
+ EV_SET(&ev, signo, EVFILT_SIGNAL, EV_ADD, 0, 0, 0);
+ ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr);
+ assert(ret == 0);
+#endif
+
+ // If we're using kqueue, the signal needs to be unblocked in order to recieve
+ // it. If using pselect/ppoll, we need to block it, and later unblock it as a
+ // part of the system call.
+ ret = pthread_sigmask(HAVE_SYS_EVENT_H ? SIG_UNBLOCK : SIG_BLOCK,
+ &new_action.sa_mask, &old_set);
+ assert(ret == 0 && "pthread_sigmask failed");
+ info.was_blocked = sigismember(&old_set, signo);
m_signals.insert({signo, info});
- g_signal_flags[signo] = 0;
return SignalHandleUP(new SignalHandle(*this, signo));
#endif
@@ -331,7 +320,6 @@ void MainLoop::UnregisterSignal(int signo) {
#if SIGNAL_POLLING_UNSUPPORTED
Error("Signal polling is not supported on this platform.");
#else
- // We undo the actions of RegisterSignal on a best-effort basis.
auto it = m_signals.find(signo);
assert(it != m_signals.end());
@@ -340,8 +328,17 @@ void MainLoop::UnregisterSignal(int signo) {
sigset_t set;
sigemptyset(&set);
sigaddset(&set, signo);
- pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK, &set,
- nullptr);
+ int ret = pthread_sigmask(it->second.was_blocked ? SIG_BLOCK : SIG_UNBLOCK,
+ &set, nullptr);
+ assert(ret == 0);
+ (void)ret;
+
+#if HAVE_SYS_EVENT_H
+ struct kevent ev;
+ EV_SET(&ev, signo, EVFILT_SIGNAL, EV_DELETE, 0, 0, 0);
+ ret = kevent(m_kqueue, &ev, 1, nullptr, 0, nullptr);
+ assert(ret == 0);
+#endif
m_signals.erase(it);
#endif
@@ -351,32 +348,31 @@ Error MainLoop::Run() {
m_terminate_request = false;
Error error;
- auto impl = RunImpl::Create(*this, error);
- if (!impl)
- return error;
+ RunImpl impl(*this);
// run until termination or until we run out of things to listen to
while (!m_terminate_request && (!m_read_fds.empty() || !m_signals.empty())) {
- error = impl->Poll();
+ error = impl.Poll();
if (error.Fail())
return error;
- impl->ForEachSignal([&](int sig) {
- auto it = m_signals.find(sig);
- if (it != m_signals.end())
- it->second.callback(*this); // Do the work
- });
- if (m_terminate_request)
- return Error();
+ impl.ProcessEvents();
- impl->ForEachReadFD([&](int fd) {
- auto it = m_read_fds.find(fd);
- if (it != m_read_fds.end())
- it->second(*this); // Do the work
- });
if (m_terminate_request)
return Error();
}
return Error();
}
+
+void MainLoop::ProcessSignal(int signo) {
+ auto it = m_signals.find(signo);
+ if (it != m_signals.end())
+ it->second.callback(*this); // Do the work
+}
+
+void MainLoop::ProcessReadObject(IOObject::WaitableHandle handle) {
+ auto it = m_read_fds.find(handle);
+ if (it != m_read_fds.end())
+ it->second(*this); // Do the work
+}
diff --git a/source/Host/common/UDPSocket.cpp b/source/Host/common/UDPSocket.cpp
index a32657aab0a6..ce8d90891b2b 100644
--- a/source/Host/common/UDPSocket.cpp
+++ b/source/Host/common/UDPSocket.cpp
@@ -28,31 +28,41 @@ const int kDomain = AF_INET;
const int kType = SOCK_DGRAM;
static const char *g_not_supported_error = "Not supported";
-} // namespace
-
-UDPSocket::UDPSocket(bool should_close, bool child_processes_inherit)
- : Socket(ProtocolUdp, should_close, child_processes_inherit) {}
+}
-UDPSocket::UDPSocket(NativeSocket socket, const UDPSocket &listen_socket)
- : Socket(ProtocolUdp, listen_socket.m_should_close_fd,
- listen_socket.m_child_processes_inherit) {
+UDPSocket::UDPSocket(NativeSocket socket) : Socket(ProtocolUdp, true, true) {
m_socket = socket;
}
+UDPSocket::UDPSocket(bool should_close, bool child_processes_inherit)
+ : Socket(ProtocolUdp, should_close, child_processes_inherit) {}
+
size_t UDPSocket::Send(const void *buf, const size_t num_bytes) {
return ::sendto(m_socket, static_cast<const char *>(buf), num_bytes, 0,
m_sockaddr, m_sockaddr.GetLength());
}
Error UDPSocket::Connect(llvm::StringRef name) {
+ return Error("%s", g_not_supported_error);
+}
+
+Error UDPSocket::Listen(llvm::StringRef name, int backlog) {
+ return Error("%s", g_not_supported_error);
+}
+
+Error UDPSocket::Accept(Socket *&socket) {
+ return Error("%s", g_not_supported_error);
+}
+
+Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
+ Socket *&socket) {
+ std::unique_ptr<UDPSocket> final_socket;
+
Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
if (log)
log->Printf("UDPSocket::%s (host/port = %s)", __FUNCTION__, name.data());
Error error;
- if (error.Fail())
- return error;
-
std::string host_str;
std::string port_str;
int32_t port = INT32_MIN;
@@ -84,11 +94,12 @@ Error UDPSocket::Connect(llvm::StringRef name) {
for (struct addrinfo *service_info_ptr = service_info_list;
service_info_ptr != nullptr;
service_info_ptr = service_info_ptr->ai_next) {
- m_socket = Socket::CreateSocket(
+ auto send_fd = CreateSocket(
service_info_ptr->ai_family, service_info_ptr->ai_socktype,
- service_info_ptr->ai_protocol, m_child_processes_inherit, error);
+ service_info_ptr->ai_protocol, child_processes_inherit, error);
if (error.Success()) {
- m_sockaddr = service_info_ptr;
+ final_socket.reset(new UDPSocket(send_fd));
+ final_socket->m_sockaddr = service_info_ptr;
break;
} else
continue;
@@ -96,17 +107,16 @@ Error UDPSocket::Connect(llvm::StringRef name) {
::freeaddrinfo(service_info_list);
- if (IsValid())
+ if (!final_socket)
return error;
SocketAddress bind_addr;
// Only bind to the loopback address if we are expecting a connection from
// localhost to avoid any firewall issues.
- const bool bind_addr_success =
- (host_str == "127.0.0.1" || host_str == "localhost")
- ? bind_addr.SetToLocalhost(kDomain, port)
- : bind_addr.SetToAnyAddress(kDomain, port);
+ const bool bind_addr_success = (host_str == "127.0.0.1" || host_str == "localhost")
+ ? bind_addr.SetToLocalhost(kDomain, port)
+ : bind_addr.SetToAnyAddress(kDomain, port);
if (!bind_addr_success) {
error.SetErrorString("Failed to get hostspec to bind for");
@@ -115,37 +125,13 @@ Error UDPSocket::Connect(llvm::StringRef name) {
bind_addr.SetPort(0); // Let the source port # be determined dynamically
- err = ::bind(m_socket, bind_addr, bind_addr.GetLength());
+ err = ::bind(final_socket->GetNativeSocket(), bind_addr, bind_addr.GetLength());
- error.Clear();
- return error;
-}
+ struct sockaddr_in source_info;
+ socklen_t address_len = sizeof (struct sockaddr_in);
+ err = ::getsockname(final_socket->GetNativeSocket(), (struct sockaddr *) &source_info, &address_len);
-Error UDPSocket::Listen(llvm::StringRef name, int backlog) {
- return Error("%s", g_not_supported_error);
-}
-
-Error UDPSocket::Accept(Socket *&socket) {
- return Error("%s", g_not_supported_error);
-}
-
-Error UDPSocket::CreateSocket() {
- Error error;
- if (IsValid())
- error = Close();
- if (error.Fail())
- return error;
- m_socket =
- Socket::CreateSocket(kDomain, kType, 0, m_child_processes_inherit, error);
- return error;
-}
-
-Error UDPSocket::Connect(llvm::StringRef name, bool child_processes_inherit,
- Socket *&socket) {
- std::unique_ptr<UDPSocket> final_socket(
- new UDPSocket(true, child_processes_inherit));
- Error error = final_socket->Connect(name);
- if (!error.Fail())
- socket = final_socket.release();
+ socket = final_socket.release();
+ error.Clear();
return error;
}
diff --git a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
index 04df0065d7bc..65cbd271e979 100644
--- a/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
+++ b/source/Plugins/ABI/SysV-arm64/ABISysV_arm64.cpp
@@ -2362,32 +2362,30 @@ ValueObjectSP ABISysV_arm64::GetReturnValueObjectImpl(
if (success)
return_valobj_sp = ValueObjectConstResult::Create(
thread.GetStackFrameAtIndex(0).get(), value, ConstString(""));
- } else if (type_flags & eTypeIsVector) {
+ } else if (type_flags & eTypeIsVector && byte_size <= 16) {
if (byte_size > 0) {
const RegisterInfo *v0_info = reg_ctx->GetRegisterInfoByName("v0", 0);
if (v0_info) {
- if (byte_size <= v0_info->byte_size) {
- std::unique_ptr<DataBufferHeap> heap_data_ap(
- new DataBufferHeap(byte_size, 0));
- const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
- RegisterValue reg_value;
- if (reg_ctx->ReadRegister(v0_info, reg_value)) {
- Error error;
- if (reg_value.GetAsMemoryData(v0_info, heap_data_ap->GetBytes(),
- heap_data_ap->GetByteSize(),
- byte_order, error)) {
- DataExtractor data(DataBufferSP(heap_data_ap.release()),
- byte_order,
- exe_ctx.GetProcessRef().GetAddressByteSize());
- return_valobj_sp = ValueObjectConstResult::Create(
- &thread, return_compiler_type, ConstString(""), data);
- }
+ std::unique_ptr<DataBufferHeap> heap_data_ap(
+ new DataBufferHeap(byte_size, 0));
+ const ByteOrder byte_order = exe_ctx.GetProcessRef().GetByteOrder();
+ RegisterValue reg_value;
+ if (reg_ctx->ReadRegister(v0_info, reg_value)) {
+ Error error;
+ if (reg_value.GetAsMemoryData(v0_info, heap_data_ap->GetBytes(),
+ heap_data_ap->GetByteSize(), byte_order,
+ error)) {
+ DataExtractor data(DataBufferSP(heap_data_ap.release()), byte_order,
+ exe_ctx.GetProcessRef().GetAddressByteSize());
+ return_valobj_sp = ValueObjectConstResult::Create(
+ &thread, return_compiler_type, ConstString(""), data);
}
}
}
}
- } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass) {
+ } else if (type_flags & eTypeIsStructUnion || type_flags & eTypeIsClass ||
+ (type_flags & eTypeIsVector && byte_size > 16)) {
DataExtractor data;
uint32_t NGRN = 0; // Search ABI docs for NGRN
diff --git a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
index 20260ee5b5c3..c824653b2e93 100644
--- a/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
+++ b/source/Plugins/DynamicLoader/MacOSX-DYLD/DynamicLoaderMacOS.cpp
@@ -434,24 +434,25 @@ Error DynamicLoaderMacOS::CanLoadImage() {
// Default assumption is that it is OK to load images.
// Only say that we cannot load images if we find the symbol in libdyld and it
- // indicates that
- // we cannot.
+ // indicates that we cannot.
if (symbol_address != LLDB_INVALID_ADDRESS) {
{
int lock_held =
m_process->ReadUnsignedIntegerFromMemory(symbol_address, 4, 0, error);
if (lock_held != 0) {
- error.SetErrorToGenericError();
+ error.SetErrorString("dyld lock held - unsafe to load images.");
}
}
} else {
// If we were unable to find _dyld_global_lock_held in any modules, or it is
- // not loaded into
- // memory yet, we may be at process startup (sitting at _dyld_start) - so we
- // should not allow
- // dlopen calls.
- error.SetErrorToGenericError();
+ // not loaded into memory yet, we may be at process startup (sitting
+ // at _dyld_start) - so we should not allow dlopen calls.
+ // But if we found more than one module then we are clearly past _dyld_start
+ // so in that case we'll default to "it's safe".
+ if (num_modules <= 1)
+ error.SetErrorString("could not find the dyld library or "
+ "the dyld lock symbol");
}
return error;
}
diff --git a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
index 8c2fc3d3aa42..ad6af8dfebd5 100644
--- a/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
+++ b/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
@@ -1946,7 +1946,9 @@ void SymbolFileDWARF::Index() {
std::vector<NameToDIE> type_index(num_compile_units);
std::vector<NameToDIE> namespace_index(num_compile_units);
- std::vector<bool> clear_cu_dies(num_compile_units, false);
+ // std::vector<bool> might be implemented using bit test-and-set, so use
+ // uint8_t instead.
+ std::vector<uint8_t> clear_cu_dies(num_compile_units, false);
auto parser_fn = [debug_info, &function_basename_index,
&function_fullname_index, &function_method_index,
&function_selector_index, &objc_class_selectors_index,
@@ -1963,22 +1965,18 @@ void SymbolFileDWARF::Index() {
return cu_idx;
};
- auto extract_fn = [debug_info](uint32_t cu_idx) {
+ auto extract_fn = [debug_info, &clear_cu_dies](uint32_t cu_idx) {
DWARFCompileUnit *dwarf_cu = debug_info->GetCompileUnitAtIndex(cu_idx);
if (dwarf_cu) {
// dwarf_cu->ExtractDIEsIfNeeded(false) will return zero if the
// DIEs for a compile unit have already been parsed.
- return std::make_pair(cu_idx, dwarf_cu->ExtractDIEsIfNeeded(false) > 1);
+ if (dwarf_cu->ExtractDIEsIfNeeded(false) > 1)
+ clear_cu_dies[cu_idx] = true;
}
- return std::make_pair(cu_idx, false);
};
// Create a task runner that extracts dies for each DWARF compile unit in a
// separate thread
- TaskRunner<std::pair<uint32_t, bool>> task_runner_extract;
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- task_runner_extract.AddTask(extract_fn, cu_idx);
-
//----------------------------------------------------------------------
// First figure out which compile units didn't have their DIEs already
// parsed and remember this. If no DIEs were parsed prior to this index
@@ -1988,48 +1986,37 @@ void SymbolFileDWARF::Index() {
// a DIE in one compile unit refers to another and the indexes accesses
// those DIEs.
//----------------------------------------------------------------------
- while (true) {
- auto f = task_runner_extract.WaitForNextCompletedTask();
- if (!f.valid())
- break;
- unsigned cu_idx;
- bool clear;
- std::tie(cu_idx, clear) = f.get();
- clear_cu_dies[cu_idx] = clear;
- }
+ TaskMapOverInt(0, num_compile_units, extract_fn);
// Now create a task runner that can index each DWARF compile unit in a
// separate
// thread so we can index quickly.
- TaskRunner<uint32_t> task_runner;
- for (uint32_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
- task_runner.AddTask(parser_fn, cu_idx);
+ TaskMapOverInt(0, num_compile_units, parser_fn);
- while (true) {
- std::future<uint32_t> f = task_runner.WaitForNextCompletedTask();
- if (!f.valid())
- break;
- uint32_t cu_idx = f.get();
-
- m_function_basename_index.Append(function_basename_index[cu_idx]);
- m_function_fullname_index.Append(function_fullname_index[cu_idx]);
- m_function_method_index.Append(function_method_index[cu_idx]);
- m_function_selector_index.Append(function_selector_index[cu_idx]);
- m_objc_class_selectors_index.Append(objc_class_selectors_index[cu_idx]);
- m_global_index.Append(global_index[cu_idx]);
- m_type_index.Append(type_index[cu_idx]);
- m_namespace_index.Append(namespace_index[cu_idx]);
- }
+ auto finalize_fn = [](NameToDIE &index, std::vector<NameToDIE> &srcs) {
+ for (auto &src : srcs)
+ index.Append(src);
+ index.Finalize();
+ };
- TaskPool::RunTasks([&]() { m_function_basename_index.Finalize(); },
- [&]() { m_function_fullname_index.Finalize(); },
- [&]() { m_function_method_index.Finalize(); },
- [&]() { m_function_selector_index.Finalize(); },
- [&]() { m_objc_class_selectors_index.Finalize(); },
- [&]() { m_global_index.Finalize(); },
- [&]() { m_type_index.Finalize(); },
- [&]() { m_namespace_index.Finalize(); });
+ TaskPool::RunTasks(
+ [&]() {
+ finalize_fn(m_function_basename_index, function_basename_index);
+ },
+ [&]() {
+ finalize_fn(m_function_fullname_index, function_fullname_index);
+ },
+ [&]() { finalize_fn(m_function_method_index, function_method_index); },
+ [&]() {
+ finalize_fn(m_function_selector_index, function_selector_index);
+ },
+ [&]() {
+ finalize_fn(m_objc_class_selectors_index, objc_class_selectors_index);
+ },
+ [&]() { finalize_fn(m_global_index, global_index); },
+ [&]() { finalize_fn(m_type_index, type_index); },
+ [&]() { finalize_fn(m_namespace_index, namespace_index); });
//----------------------------------------------------------------------
// Keep memory down by clearing DIEs for any compile units if indexing
diff --git a/source/Target/ThreadPlanCallUserExpression.cpp b/source/Target/ThreadPlanCallUserExpression.cpp
index 679040d09a02..15cbd0baa9a6 100644
--- a/source/Target/ThreadPlanCallUserExpression.cpp
+++ b/source/Target/ThreadPlanCallUserExpression.cpp
@@ -60,6 +60,12 @@ void ThreadPlanCallUserExpression::GetDescription(
ThreadPlanCallFunction::GetDescription(s, level);
}
+void ThreadPlanCallUserExpression::DidPush() {
+ ThreadPlanCallFunction::DidPush();
+ if (m_user_expression_sp)
+ m_user_expression_sp->WillStartExecuting();
+}
+
void ThreadPlanCallUserExpression::WillPop() {
ThreadPlanCallFunction::WillPop();
if (m_user_expression_sp)
@@ -113,3 +119,8 @@ StopInfoSP ThreadPlanCallUserExpression::GetRealStopInfo() {
return stop_info_sp;
}
+
+void ThreadPlanCallUserExpression::DoTakedown(bool success) {
+ ThreadPlanCallFunction::DoTakedown(success);
+ m_user_expression_sp->DidFinishExecuting();
+}
diff --git a/source/Utility/TaskPool.cpp b/source/Utility/TaskPool.cpp
index 244e64fdb5fb..d8306dc7dc8f 100644
--- a/source/Utility/TaskPool.cpp
+++ b/source/Utility/TaskPool.cpp
@@ -73,3 +73,26 @@ void TaskPoolImpl::Worker(TaskPoolImpl *pool) {
f();
}
}
+
+void TaskMapOverInt(size_t begin, size_t end,
+ std::function<void(size_t)> const &func) {
+ std::atomic<size_t> idx{begin};
+ size_t num_workers =
+ std::min<size_t>(end, std::thread::hardware_concurrency());
+
+ auto wrapper = [&idx, end, &func]() {
+ while (true) {
+ size_t i = idx.fetch_add(1);
+ if (i >= end)
+ break;
+ func(i);
+ }
+ };
+
+ std::vector<std::future<void>> futures;
+ futures.reserve(num_workers);
+ for (size_t i = 0; i < num_workers; i++)
+ futures.push_back(TaskPool::AddTask(wrapper));
+ for (size_t i = 0; i < num_workers; i++)
+ futures[i].wait();
+}