Add initial support to trace spawned threads in a process on Linux.
git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@171864 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Plugins/Process/Linux/ProcessLinux.cpp b/source/Plugins/Process/Linux/ProcessLinux.cpp
index 6a766d7..6118a09 100644
--- a/source/Plugins/Process/Linux/ProcessLinux.cpp
+++ b/source/Plugins/Process/Linux/ProcessLinux.cpp
@@ -97,22 +97,7 @@
bool
ProcessLinux::UpdateThreadList(ThreadList &old_thread_list, ThreadList &new_thread_list)
{
- LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_THREAD));
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessLinux::%s() (pid = %" PRIu64 ")", __FUNCTION__, GetID());
-
- // Update the process thread list with this new thread.
- // FIXME: We should be using tid, not pid.
- assert(m_monitor);
- ThreadSP thread_sp (old_thread_list.FindThreadByID (GetID(), false));
- if (!thread_sp) {
- thread_sp.reset(new POSIXThread(*this, GetID()));
- }
-
- if (log && log->GetMask().Test(POSIX_LOG_VERBOSE))
- log->Printf ("ProcessLinux::%s() updated pid = %" PRIu64, __FUNCTION__, GetID());
- new_thread_list.AddThread(thread_sp);
-
+ new_thread_list = old_thread_list;
return new_thread_list.GetSize(false) > 0;
}
diff --git a/source/Plugins/Process/Linux/ProcessMonitor.cpp b/source/Plugins/Process/Linux/ProcessMonitor.cpp
index b71f0f9..f36a9ee 100644
--- a/source/Plugins/Process/Linux/ProcessMonitor.cpp
+++ b/source/Plugins/Process/Linux/ProcessMonitor.cpp
@@ -985,6 +985,7 @@
const size_t err_len = 1024;
char err_str[err_len];
lldb::pid_t pid;
+ long ptrace_opts = 0;
lldb::ThreadSP inferior;
LogSP log (ProcessPOSIXLog::GetLogIfAllCategoriesSet (POSIX_LOG_PROCESS));
@@ -1102,7 +1103,12 @@
// Have the child raise an event on exit. This is used to keep the child in
// limbo until it is destroyed.
- if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)PTRACE_O_TRACEEXIT) < 0)
+ ptrace_opts |= PTRACE_O_TRACEEXIT;
+
+ // Have the tracer trace threads which spawn in the inferior process.
+ ptrace_opts |= PTRACE_O_TRACEFORK | PTRACE_O_TRACEVFORK | PTRACE_O_TRACECLONE;
+
+ if (PTRACE(PTRACE_SETOPTIONS, pid, NULL, (void*)ptrace_opts) < 0)
{
args->m_error.SetErrorToErrno();
goto FINISH;
@@ -1282,6 +1288,17 @@
assert(false && "Unexpected SIGTRAP code!");
break;
+ case (SIGTRAP | (PTRACE_EVENT_FORK << 8)):
+ case (SIGTRAP | (PTRACE_EVENT_VFORK << 8)):
+ case (SIGTRAP | (PTRACE_EVENT_CLONE << 8)):
+ {
+ unsigned long tid = 0;
+ if (!monitor->GetEventMessage(pid, &tid))
+ tid = -1;
+ message = ProcessMessage::NewThread(pid, tid);
+ break;
+ }
+
case (SIGTRAP | (PTRACE_EVENT_EXIT << 8)):
{
// The inferior process is about to exit. Maintain the process in a
diff --git a/source/Plugins/Process/POSIX/POSIXStopInfo.cpp b/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
index 3dd3c86..b9765b6 100644
--- a/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
+++ b/source/Plugins/Process/POSIX/POSIXStopInfo.cpp
@@ -58,3 +58,32 @@
{
return ProcessMessage::GetCrashReasonString(m_crash_reason);
}
+
+//===----------------------------------------------------------------------===//
+// POSIXNewThreadStopInfo
+
+POSIXNewThreadStopInfo::~POSIXNewThreadStopInfo() { }
+
+lldb::StopReason
+POSIXNewThreadStopInfo::GetStopReason() const
+{
+ return lldb::eStopReasonNone;
+}
+
+const char *
+POSIXNewThreadStopInfo::GetDescription()
+{
+ return "thread spawned";
+}
+
+bool
+POSIXNewThreadStopInfo::ShouldStop(Event *event_ptr)
+{
+ return false;
+}
+
+bool
+POSIXNewThreadStopInfo::ShouldNotify(Event *event_ptr)
+{
+ return false;
+}
diff --git a/source/Plugins/Process/POSIX/POSIXStopInfo.h b/source/Plugins/Process/POSIX/POSIXStopInfo.h
index c510377..7c5be3d 100644
--- a/source/Plugins/Process/POSIX/POSIXStopInfo.h
+++ b/source/Plugins/Process/POSIX/POSIXStopInfo.h
@@ -89,4 +89,32 @@
ProcessMessage::CrashReason m_crash_reason;
};
+//===----------------------------------------------------------------------===//
+/// @class POSIXNewThreadStopInfo
+/// @brief Represents the stop state of process when a new thread is spawned.
+///
+
+class POSIXNewThreadStopInfo
+ : public POSIXStopInfo
+{
+public:
+ POSIXNewThreadStopInfo (POSIXThread &thread)
+ : POSIXStopInfo (thread, 0)
+ { }
+
+ ~POSIXNewThreadStopInfo();
+
+ lldb::StopReason
+ GetStopReason() const;
+
+ const char *
+ GetDescription();
+
+ bool
+ ShouldStop(lldb_private::Event *event_ptr);
+
+ bool
+ ShouldNotify(lldb_private::Event *event_ptr);
+};
+
#endif
diff --git a/source/Plugins/Process/POSIX/POSIXThread.cpp b/source/Plugins/Process/POSIX/POSIXThread.cpp
index e7848c0..ce43913 100644
--- a/source/Plugins/Process/POSIX/POSIXThread.cpp
+++ b/source/Plugins/Process/POSIX/POSIXThread.cpp
@@ -226,6 +226,10 @@
case ProcessMessage::eCrashMessage:
CrashNotify(message);
break;
+
+ case ProcessMessage::eNewThreadMessage:
+ ThreadNotify(message);
+ break;
}
}
@@ -301,6 +305,12 @@
SetResumeSignal(signo);
}
+void
+POSIXThread::ThreadNotify(const ProcessMessage &message)
+{
+ m_stop_info = lldb::StopInfoSP(new POSIXNewThreadStopInfo(*this));
+}
+
unsigned
POSIXThread::GetRegisterIndexFromOffset(unsigned offset)
{
diff --git a/source/Plugins/Process/POSIX/POSIXThread.h b/source/Plugins/Process/POSIX/POSIXThread.h
index 95280d4..7aad671 100644
--- a/source/Plugins/Process/POSIX/POSIXThread.h
+++ b/source/Plugins/Process/POSIX/POSIXThread.h
@@ -98,6 +98,7 @@
void SignalNotify(const ProcessMessage &message);
void SignalDeliveredNotify(const ProcessMessage &message);
void CrashNotify(const ProcessMessage &message);
+ void ThreadNotify(const ProcessMessage &message);
lldb_private::Unwind *
GetUnwinder();
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.cpp b/source/Plugins/Process/POSIX/ProcessMessage.cpp
index a8b8e95..cefacc3 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.cpp
+++ b/source/Plugins/Process/POSIX/ProcessMessage.cpp
@@ -224,6 +224,9 @@
case eCrashMessage:
str = "eCrashMessage";
break;
+ case eNewThreadMessage:
+ str = "eNewThreadMessage";
+ break;
}
#endif
diff --git a/source/Plugins/Process/POSIX/ProcessMessage.h b/source/Plugins/Process/POSIX/ProcessMessage.h
index 826567e..7eca5c8 100644
--- a/source/Plugins/Process/POSIX/ProcessMessage.h
+++ b/source/Plugins/Process/POSIX/ProcessMessage.h
@@ -29,7 +29,8 @@
eSignalDeliveredMessage,
eTraceMessage,
eBreakpointMessage,
- eCrashMessage
+ eCrashMessage,
+ eNewThreadMessage
};
enum CrashReason
@@ -111,6 +112,11 @@
return message;
}
+ /// Indicates that the thread @p tid was spawned.
+ static ProcessMessage NewThread(lldb::tid_t parent_tid, lldb::tid_t child_tid) {
+ return ProcessMessage(parent_tid, eNewThreadMessage, child_tid);
+ }
+
int GetExitStatus() const {
assert(GetKind() == eExitMessage || GetKind() == eLimboMessage);
return m_status;
@@ -137,6 +143,11 @@
return m_addr;
}
+ lldb::tid_t GetChildTID() const {
+ assert(GetKind() == eNewThreadMessage);
+ return m_child_tid;
+ }
+
static const char *
GetCrashReasonString(CrashReason reason);
@@ -159,13 +170,23 @@
m_kind(kind),
m_crash_reason(eInvalidCrashReason),
m_status(status),
- m_addr(addr) { }
+ m_addr(addr),
+ m_child_tid(0) { }
+
+ ProcessMessage(lldb::tid_t tid, Kind kind, lldb::tid_t child_tid)
+ : m_tid(tid),
+ m_kind(kind),
+ m_crash_reason(eInvalidCrashReason),
+ m_status(0),
+ m_addr(0),
+ m_child_tid(child_tid) { }
lldb::tid_t m_tid;
Kind m_kind : 8;
CrashReason m_crash_reason : 8;
int m_status;
lldb::addr_t m_addr;
+ lldb::tid_t m_child_tid;
};
#endif // #ifndef liblldb_ProcessMessage_H_
diff --git a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
index a694865..980778f 100644
--- a/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
+++ b/source/Plugins/Process/POSIX/ProcessPOSIX.cpp
@@ -361,13 +361,26 @@
case ProcessMessage::eSignalMessage:
case ProcessMessage::eSignalDeliveredMessage:
- SetPrivateState(eStateStopped);
- break;
+ {
+ lldb::tid_t tid = message.GetTID();
+ lldb::tid_t pid = GetID();
+ if (tid == pid) {
+ SetPrivateState(eStateStopped);
+ break;
+ } else {
+ // FIXME: Ignore any signals generated by children.
+ return;
+ }
+ }
case ProcessMessage::eCrashMessage:
// FIXME: Update stop reason as per bugzilla 14598
SetPrivateState(eStateStopped);
break;
+
+ case ProcessMessage::eNewThreadMessage:
+ SetPrivateState(eStateStopped);
+ break;
}
m_message_queue.push(message);
@@ -395,6 +408,12 @@
POSIXThread *thread = static_cast<POSIXThread*>(
GetThreadList().FindThreadByID(tid, false).get());
+ if (message.GetKind() == ProcessMessage::eNewThreadMessage) {
+ ThreadSP thread_sp;
+ thread_sp.reset(new POSIXThread(*this, message.GetChildTID()));
+ m_thread_list.AddThread(thread_sp);
+ }
+
assert(thread);
thread->Notify(message);