Fix signal handling for POSIX (only tested on Linux) processes in multi-threaded programs.
Also fix a related issue where if a thread exits after a thread continue, lldb would hang.
llvm-svn: 185944
diff --git a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
index 512639c..fe61798 100644
--- a/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
+++ b/lldb/source/Plugins/Process/Linux/ProcessMonitor.cpp
@@ -1236,6 +1236,8 @@
log->Printf ("ProcessMonitor::%s() adding pid = %" PRIu64, __FUNCTION__, pid);
process.GetThreadList().AddThread(inferior);
+ process.AddThreadForInitialStopIfNeeded(pid);
+
// Let our process instance know the thread has stopped.
process.SendMessage(ProcessMessage::Trace(pid));
@@ -1294,7 +1296,6 @@
// Use a map to keep track of the threads which we have attached/need to attach.
Host::TidMap tids_to_attach;
-
if (pid <= 1)
{
args->m_error.SetErrorToGenericError();
@@ -1360,6 +1361,7 @@
log->Printf ("ProcessMonitor::%s() adding tid = %" PRIu64, __FUNCTION__, tid);
process.GetThreadList().AddThread(inferior);
it->second = true;
+ process.AddThreadForInitialStopIfNeeded(tid);
}
}
}
@@ -1513,7 +1515,7 @@
if (!monitor->GetEventMessage(pid, &data))
data = -1;
if (log)
- log->Printf ("ProcessMonitor::%s() received exit event, data = %lx, pid = %" PRIu64, __FUNCTION__, data, pid);
+ log->Printf ("ProcessMonitor::%s() received limbo event, data = %lx, pid = %" PRIu64, __FUNCTION__, data, pid);
message = ProcessMessage::Limbo(pid, (data >> 8));
break;
}
@@ -1711,6 +1713,27 @@
return true;
break;
+ case ProcessMessage::eSignalMessage:
+ if (log)
+ log->Printf ("ProcessMonitor::%s(bp) handling message", __FUNCTION__);
+ if (WSTOPSIG(status) == SIGSTOP)
+ {
+ m_process->AddThreadForInitialStopIfNeeded(tid);
+ thread->SetState(lldb::eStateStopped);
+ }
+ else
+ {
+ m_process->SendMessage(message);
+ // This isn't the stop we were expecting, but the thread is
+ // stopped. SendMessage will handle processing of this event,
+ // but we need to resume here to get the stop we are waiting
+ // for (otherwise the thread will stop again immediately when
+ // we try to resume).
+ if (wait_pid == tid)
+ Resume(wait_pid, eResumeSignalNone);
+ }
+ break;
+
case ProcessMessage::eSignalDeliveredMessage:
// This is the stop we're expecting.
if (wait_pid == tid && WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP && info.si_code == SI_TKILL)
@@ -1721,7 +1744,6 @@
return true;
}
// else fall-through
- case ProcessMessage::eSignalMessage:
case ProcessMessage::eBreakpointMessage:
case ProcessMessage::eTraceMessage:
case ProcessMessage::eWatchpointMessage: