diff options
Diffstat (limited to 'lldb')
4 files changed, 35 insertions, 16 deletions
diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp index ac8a0b94a24..177153afa0c 100644 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.cpp @@ -502,8 +502,8 @@ SingleStepOperation::Execute(ProcessMonitor *monitor) class SiginfoOperation : public Operation { public: - SiginfoOperation(lldb::tid_t tid, void *info, bool &result) - : m_tid(tid), m_info(info), m_result(result) { } + SiginfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err) + : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { } void Execute(ProcessMonitor *monitor); @@ -511,6 +511,7 @@ private: lldb::tid_t m_tid; void *m_info; bool &m_result; + int &m_err; }; void @@ -518,9 +519,10 @@ SiginfoOperation::Execute(ProcessMonitor *monitor) { struct ptrace_lwpinfo plwp; - if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) + if (PTRACE(PT_LWPINFO, m_tid, (caddr_t)&plwp, sizeof(plwp))) { m_result = false; - else { + m_err = errno; + } else { memcpy(m_info, &plwp.pl_siginfo, sizeof(siginfo_t)); m_result = true; } @@ -1060,8 +1062,9 @@ ProcessMonitor::MonitorCallback(void *callback_baton, ProcessFreeBSD *process = monitor->m_process; bool stop_monitoring; siginfo_t info; + int ptrace_err; - if (!monitor->GetSignalInfo(pid, &info)) + if (!monitor->GetSignalInfo(pid, &info, ptrace_err)) stop_monitoring = true; // pid is gone. Bail. else { switch (info.si_signo) @@ -1488,10 +1491,10 @@ ProcessMonitor::BringProcessIntoLimbo() } bool -ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo) +ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err) { bool result; - SiginfoOperation op(tid, siginfo, result); + SiginfoOperation op(tid, siginfo, result, ptrace_err); DoOperation(&op); return result; } diff --git a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h index 9c630049caf..5530ca3afbb 100644 --- a/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/FreeBSD/ProcessMonitor.h @@ -132,7 +132,7 @@ public: /// Writes a siginfo_t structure corresponding to the given thread ID to the /// memory region pointed to by @p siginfo. bool - GetSignalInfo(lldb::tid_t tid, void *siginfo); + GetSignalInfo(lldb::tid_t tid, void *siginfo, int &errno); /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) /// corresponding to the given thread IDto the memory pointed to by @p diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp index 98992472320..7e4aeea954d 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp @@ -652,8 +652,8 @@ SingleStepOperation::Execute(ProcessMonitor *monitor) class SiginfoOperation : public Operation { public: - SiginfoOperation(lldb::tid_t tid, void *info, bool &result) - : m_tid(tid), m_info(info), m_result(result) { } + SiginfoOperation(lldb::tid_t tid, void *info, bool &result, int &ptrace_err) + : m_tid(tid), m_info(info), m_result(result), m_err(ptrace_err) { } void Execute(ProcessMonitor *monitor); @@ -661,13 +661,16 @@ private: lldb::tid_t m_tid; void *m_info; bool &m_result; + int &m_err; }; void SiginfoOperation::Execute(ProcessMonitor *monitor) { - if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info)) + if (PTRACE(PTRACE_GETSIGINFO, m_tid, NULL, m_info)) { m_result = false; + m_err = errno; + } else m_result = true; } @@ -1203,9 +1206,22 @@ ProcessMonitor::MonitorCallback(void *callback_baton, assert(process); bool stop_monitoring; siginfo_t info; + int ptrace_err; - if (!monitor->GetSignalInfo(pid, &info)) - stop_monitoring = true; // pid is gone. Bail. + if (!monitor->GetSignalInfo(pid, &info, ptrace_err)) { + if (ptrace_err == EINVAL) { + // inferior process is in 'group-stop', so deliver SIGSTOP signal + if (!monitor->Resume(pid, SIGSTOP)) { + assert(0 && "SIGSTOP delivery failed while in 'group-stop' state"); + } + stop_monitoring = false; + } else { + // ptrace(GETSIGINFO) failed (but not due to group-stop). Most likely, + // this means the child pid is gone (or not being debugged) therefore + // stop the monitor thread. + stop_monitoring = true; + } + } else { switch (info.si_signo) { @@ -1632,10 +1648,10 @@ ProcessMonitor::BringProcessIntoLimbo() } bool -ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo) +ProcessMonitor::GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err) { bool result; - SiginfoOperation op(tid, siginfo, result); + SiginfoOperation op(tid, siginfo, result, ptrace_err); DoOperation(&op); return result; } diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h index 4594ff4a366..63b487e1808 100644 --- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.h +++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.h @@ -134,7 +134,7 @@ public: /// Writes a siginfo_t structure corresponding to the given thread ID to the /// memory region pointed to by @p siginfo. bool - GetSignalInfo(lldb::tid_t tid, void *siginfo); + GetSignalInfo(lldb::tid_t tid, void *siginfo, int &ptrace_err); /// Writes the raw event message code (vis-a-vis PTRACE_GETEVENTMSG) /// corresponding to the given thread IDto the memory pointed to by @p |

