summaryrefslogtreecommitdiff
path: root/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
committerDimitry Andric <dim@FreeBSD.org>2021-02-16 20:13:02 +0000
commitb60736ec1405bb0a8dd40989f67ef4c93da068ab (patch)
tree5c43fbb7c9fc45f0f87e0e6795a86267dbd12f9d /lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
parentcfca06d7963fa0909f90483b42a6d7d194d01e08 (diff)
Diffstat (limited to 'lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp')
-rw-r--r--lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp186
1 files changed, 111 insertions, 75 deletions
diff --git a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
index 5109022d80dd..57f0eb3cceb6 100644
--- a/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
+++ b/lldb/source/Plugins/Process/NetBSD/NativeProcessNetBSD.cpp
@@ -98,18 +98,7 @@ NativeProcessNetBSD::Factory::Launch(ProcessLaunchInfo &launch_info,
pid, launch_info.GetPTY().ReleasePrimaryFileDescriptor(), native_delegate,
Info.GetArchitecture(), mainloop));
- // Enable event reporting
- ptrace_event_t events;
- status = PtraceWrapper(PT_GET_EVENT_MASK, pid, &events, sizeof(events));
- if (status.Fail())
- return status.ToError();
- // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN?
- events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
- status = PtraceWrapper(PT_SET_EVENT_MASK, pid, &events, sizeof(events));
- if (status.Fail())
- return status.ToError();
-
- status = process_up->ReinitializeThreads();
+ status = process_up->SetupTrace();
if (status.Fail())
return status.ToError();
@@ -218,10 +207,14 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
// Get details on the signal raised.
if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_GET_SIGINFO failed {0}", siginfo_err);
return;
}
- NativeThreadNetBSD* thread = nullptr;
+ LLDB_LOG(log, "got SIGTRAP, pid = {0}, lwpid = {1}, si_code = {2}", pid,
+ info.psi_lwpid, info.psi_siginfo.si_code);
+ NativeThreadNetBSD *thread = nullptr;
+
if (info.psi_lwpid > 0) {
for (const auto &t : m_threads) {
if (t->GetID() == static_cast<lldb::tid_t>(info.psi_lwpid)) {
@@ -231,8 +224,7 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
static_cast<NativeThreadNetBSD *>(t.get())->SetStoppedWithNoReason();
}
if (!thread)
- LLDB_LOG(log,
- "thread not found in m_threads, pid = {0}, LWP = {1}", pid,
+ LLDB_LOG(log, "thread not found in m_threads, pid = {0}, LWP = {1}", pid,
info.psi_lwpid);
}
@@ -243,12 +235,12 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
FixupBreakpointPCAsNeeded(*thread);
}
SetState(StateType::eStateStopped, true);
- break;
+ return;
case TRAP_TRACE:
if (thread)
thread->SetStoppedByTrace();
SetState(StateType::eStateStopped, true);
- break;
+ return;
case TRAP_EXEC: {
Status error = ReinitializeThreads();
if (error.Fail()) {
@@ -262,7 +254,8 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
for (const auto &thread : m_threads)
static_cast<NativeThreadNetBSD &>(*thread).SetStoppedByExec();
SetState(StateType::eStateStopped, true);
- } break;
+ return;
+ }
case TRAP_LWP: {
ptrace_state_t pst;
Status error = PtraceWrapper(PT_GET_PROCESS_STATE, pid, &pst, sizeof(pst));
@@ -272,35 +265,31 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
}
switch (pst.pe_report_event) {
- case PTRACE_LWP_CREATE: {
- LLDB_LOG(log,
- "monitoring new thread, pid = {0}, LWP = {1}", pid,
- pst.pe_lwp);
- NativeThreadNetBSD& t = AddThread(pst.pe_lwp);
- error = t.CopyWatchpointsFrom(
- static_cast<NativeThreadNetBSD &>(*GetCurrentThread()));
- if (error.Fail()) {
- LLDB_LOG(log,
- "failed to copy watchpoints to new thread {0}: {1}",
- pst.pe_lwp, error);
- SetState(StateType::eStateInvalid);
- return;
- }
- } break;
- case PTRACE_LWP_EXIT:
- LLDB_LOG(log,
- "removing exited thread, pid = {0}, LWP = {1}", pid,
- pst.pe_lwp);
- RemoveThread(pst.pe_lwp);
- break;
+ case PTRACE_LWP_CREATE: {
+ LLDB_LOG(log, "monitoring new thread, pid = {0}, LWP = {1}", pid,
+ pst.pe_lwp);
+ NativeThreadNetBSD &t = AddThread(pst.pe_lwp);
+ error = t.CopyWatchpointsFrom(
+ static_cast<NativeThreadNetBSD &>(*GetCurrentThread()));
+ if (error.Fail()) {
+ LLDB_LOG(log, "failed to copy watchpoints to new thread {0}: {1}",
+ pst.pe_lwp, error);
+ SetState(StateType::eStateInvalid);
+ return;
+ }
+ } break;
+ case PTRACE_LWP_EXIT:
+ LLDB_LOG(log, "removing exited thread, pid = {0}, LWP = {1}", pid,
+ pst.pe_lwp);
+ RemoveThread(pst.pe_lwp);
+ break;
}
- error = PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void*>(1), 0);
- if (error.Fail()) {
+ error = PtraceWrapper(PT_CONTINUE, pid, reinterpret_cast<void *>(1), 0);
+ if (error.Fail())
SetState(StateType::eStateInvalid);
- return;
- }
- } break;
+ return;
+ }
case TRAP_DBREG: {
if (!thread)
break;
@@ -308,29 +297,42 @@ void NativeProcessNetBSD::MonitorSIGTRAP(lldb::pid_t pid) {
auto &regctx = static_cast<NativeRegisterContextNetBSD &>(
thread->GetRegisterContext());
uint32_t wp_index = LLDB_INVALID_INDEX32;
- Status error = regctx.GetWatchpointHitIndex(wp_index,
- (uintptr_t)info.psi_siginfo.si_addr);
+ Status error = regctx.GetWatchpointHitIndex(
+ wp_index, (uintptr_t)info.psi_siginfo.si_addr);
if (error.Fail())
LLDB_LOG(log,
"received error while checking for watchpoint hits, pid = "
- "{0}, LWP = {1}, error = {2}", pid, info.psi_lwpid, error);
+ "{0}, LWP = {1}, error = {2}",
+ pid, info.psi_lwpid, error);
if (wp_index != LLDB_INVALID_INDEX32) {
thread->SetStoppedByWatchpoint(wp_index);
regctx.ClearWatchpointHit(wp_index);
SetState(StateType::eStateStopped, true);
- break;
+ return;
}
thread->SetStoppedByTrace();
SetState(StateType::eStateStopped, true);
- } break;
+ return;
}
+ }
+
+ // Either user-generated SIGTRAP or an unknown event that would
+ // otherwise leave the debugger hanging.
+ LLDB_LOG(log, "unknown SIGTRAP, passing to generic handler");
+ MonitorSignal(pid, SIGTRAP);
}
void NativeProcessNetBSD::MonitorSignal(lldb::pid_t pid, int signal) {
+ Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
ptrace_siginfo_t info;
+
const auto siginfo_err =
PtraceWrapper(PT_GET_SIGINFO, pid, &info, sizeof(info));
+ if (siginfo_err.Fail()) {
+ LLDB_LOG(log, "PT_LWPINFO failed {0}", siginfo_err);
+ return;
+ }
for (const auto &abs_thread : m_threads) {
NativeThreadNetBSD &thread = static_cast<NativeThreadNetBSD &>(*abs_thread);
@@ -489,16 +491,14 @@ Status NativeProcessNetBSD::Resume(const ResumeActionList &resume_actions) {
signal = siginfo->psi_siginfo.si_signo;
}
- ret = PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1),
- signal);
+ ret =
+ PtraceWrapper(PT_CONTINUE, GetID(), reinterpret_cast<void *>(1), signal);
if (ret.Success())
SetState(eStateRunning, true);
return ret;
}
-Status NativeProcessNetBSD::Halt() {
- return PtraceWrapper(PT_STOP, GetID());
-}
+Status NativeProcessNetBSD::Halt() { return PtraceWrapper(PT_STOP, GetID()); }
Status NativeProcessNetBSD::Detach() {
Status error;
@@ -662,8 +662,8 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
if (vm[i].kve_path[0])
info.SetName(vm[i].kve_path);
- m_mem_region_cache.emplace_back(
- info, FileSpec(info.GetName().GetCString()));
+ m_mem_region_cache.emplace_back(info,
+ FileSpec(info.GetName().GetCString()));
}
free(vm);
@@ -684,15 +684,6 @@ Status NativeProcessNetBSD::PopulateMemoryRegionCache() {
return Status();
}
-Status NativeProcessNetBSD::AllocateMemory(size_t size, uint32_t permissions,
- lldb::addr_t &addr) {
- return Status("Unimplemented");
-}
-
-Status NativeProcessNetBSD::DeallocateMemory(lldb::addr_t addr) {
- return Status("Unimplemented");
-}
-
lldb::addr_t NativeProcessNetBSD::GetSharedLibraryInfoAddress() {
// punt on this for now
return LLDB_INVALID_ADDRESS;
@@ -710,21 +701,47 @@ Status NativeProcessNetBSD::SetBreakpoint(lldb::addr_t addr, uint32_t size,
Status NativeProcessNetBSD::GetLoadedModuleFileSpec(const char *module_path,
FileSpec &file_spec) {
- return Status("Unimplemented");
+ Status error = PopulateMemoryRegionCache();
+ if (error.Fail())
+ return error;
+
+ FileSpec module_file_spec(module_path);
+ FileSystem::Instance().Resolve(module_file_spec);
+
+ file_spec.Clear();
+ for (const auto &it : m_mem_region_cache) {
+ if (it.second.GetFilename() == module_file_spec.GetFilename()) {
+ file_spec = it.second;
+ return Status();
+ }
+ }
+ return Status("Module file (%s) not found in process' memory map!",
+ module_file_spec.GetFilename().AsCString());
}
Status NativeProcessNetBSD::GetFileLoadAddress(const llvm::StringRef &file_name,
lldb::addr_t &load_addr) {
load_addr = LLDB_INVALID_ADDRESS;
- return Status();
+ Status error = PopulateMemoryRegionCache();
+ if (error.Fail())
+ return error;
+
+ FileSpec file(file_name);
+ for (const auto &it : m_mem_region_cache) {
+ if (it.second == file) {
+ load_addr = it.first.GetRange().GetRangeBase();
+ return Status();
+ }
+ }
+ return Status("No load address found for file %s.", file_name.str().c_str());
}
void NativeProcessNetBSD::SigchldHandler() {
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS));
// Process all pending waitpid notifications.
int status;
- ::pid_t wait_pid =
- llvm::sys::RetryAfterSignal(-1, 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.
@@ -806,12 +823,13 @@ Status NativeProcessNetBSD::Attach() {
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 ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid,
- m_pid, nullptr, WALLSIG)) < 0)
+ if ((wstatus = llvm::sys::RetryAfterSignal(-1, waitpid, m_pid, nullptr,
+ WALLSIG)) < 0)
return Status(errno, eErrorTypePOSIX);
- /* Initialize threads */
- status = ReinitializeThreads();
+ // Initialize threads and tracing status
+ // NB: this needs to be called before we set thread state
+ status = SetupTrace();
if (status.Fail())
return status;
@@ -819,7 +837,8 @@ Status NativeProcessNetBSD::Attach() {
static_cast<NativeThreadNetBSD &>(*thread).SetStoppedBySignal(SIGSTOP);
// Let our process instance know the thread has stopped.
- SetState(StateType::eStateStopped);
+ SetCurrentThreadID(m_threads.front()->GetID());
+ SetState(StateType::eStateStopped, false);
return Status();
}
@@ -864,7 +883,8 @@ Status NativeProcessNetBSD::WriteMemory(lldb::addr_t addr, const void *buf,
io.piod_len = size;
do {
- io.piod_addr = const_cast<void *>(static_cast<const void *>(src + bytes_written));
+ io.piod_addr =
+ const_cast<void *>(static_cast<const void *>(src + bytes_written));
io.piod_offs = (void *)(addr + bytes_written);
Status error = NativeProcessNetBSD::PtraceWrapper(PT_IO, GetID(), &io);
@@ -909,6 +929,22 @@ NativeProcessNetBSD::GetAuxvData() const {
return std::move(buf);
}
+Status NativeProcessNetBSD::SetupTrace() {
+ // Enable event reporting
+ ptrace_event_t events;
+ Status status =
+ PtraceWrapper(PT_GET_EVENT_MASK, GetID(), &events, sizeof(events));
+ if (status.Fail())
+ return status;
+ // TODO: PTRACE_FORK | PTRACE_VFORK | PTRACE_POSIX_SPAWN?
+ events.pe_set_event |= PTRACE_LWP_CREATE | PTRACE_LWP_EXIT;
+ status = PtraceWrapper(PT_SET_EVENT_MASK, GetID(), &events, sizeof(events));
+ if (status.Fail())
+ return status;
+
+ return ReinitializeThreads();
+}
+
Status NativeProcessNetBSD::ReinitializeThreads() {
// Clear old threads
m_threads.clear();