summaryrefslogtreecommitdiffstats
path: root/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
diff options
context:
space:
mode:
authorChaoren Lin <chaorenl@google.com>2015-02-03 01:50:49 +0000
committerChaoren Lin <chaorenl@google.com>2015-02-03 01:50:49 +0000
commit03f12d6b224cb6691a4fee4e08adc156a3a8fd28 (patch)
tree4366c7eec81220240dd11b201729b8b078c39590 /lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
parentae29d39570cacf4c82590162a26d89bacbb6d8d3 (diff)
downloadbcm5719-llvm-03f12d6b224cb6691a4fee4e08adc156a3a8fd28.tar.gz
bcm5719-llvm-03f12d6b224cb6691a4fee4e08adc156a3a8fd28.zip
llgs: more work on thread stepping.
See https://github.com/tfiala/lldb/issues/75. Not fixed yet but continuing to push this further. Fixes: * Resume() now skips doing deferred notifications if we're doing a vCont;{c,C}. In this case, we're trying to start something up, not defer a stop notification. The default thread action stop mode pickup was triggering a stop because it had at least one stop, which was wrong in the case of a continue. (Bug introduced by previous change.) * Added a variant to ThreadStateCoordinator to specify a set of thread ids to be skipped when triggering stop notifications to non-stopped threads on a deferred signal call. For the case of a stepping thread, it is actually told to step (and is running) for a brief moment, but the thread state coordinator would think it needed to send the stepping thread a stop, which id doesn't need to do. This facility allows me to get around that cleanly. With this change, behavior is now reduced to something I think is essentially a different bug: * Doing a step into libc code from my code crashes llgs. * Doing a next out of a function in my own code crashes llgs. llvm-svn: 227912
Diffstat (limited to 'lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp')
-rw-r--r--lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp47
1 files changed, 41 insertions, 6 deletions
diff --git a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
index eaf83d1f2c2..5c297589172 100644
--- a/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
+++ b/lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp
@@ -2532,8 +2532,10 @@ NativeProcessLinux::MonitorSignal(const siginfo_t *info, lldb::pid_t pid, bool e
GetID (),
pid);
- // An inferior thread just stopped. Mark it as such.
- reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (signo);
+ // An inferior thread just stopped, but was not the primary cause of the process stop.
+ // Instead, something else (like a breakpoint or step) caused the stop. Mark the
+ // stop signal as 0 to let lldb know this isn't the important stop.
+ reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStoppedBySignal (0);
SetCurrentThreadID (thread_sp->GetID ());
// Tell the thread state coordinator about the stop.
@@ -2656,11 +2658,14 @@ NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
if (log)
log->Printf ("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__, GetID ());
- int deferred_signal_tid = LLDB_INVALID_THREAD_ID;
+ lldb::tid_t deferred_signal_tid = LLDB_INVALID_THREAD_ID;
+ lldb::tid_t deferred_signal_skip_tid = LLDB_INVALID_THREAD_ID;
int deferred_signo = 0;
NativeThreadProtocolSP deferred_signal_thread_sp;
+ int resume_count = 0;
- std::vector<NativeThreadProtocolSP> new_stop_threads;
+
+ // std::vector<NativeThreadProtocolSP> new_stop_threads;
// Scope for threads mutex.
{
@@ -2692,6 +2697,7 @@ NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
Resume (tid_to_resume, (signo > 0) ? signo : LLDB_INVALID_SIGNAL_NUMBER);
},
CoordinatorErrorHandler);
+ ++resume_count;
break;
}
@@ -2713,6 +2719,16 @@ NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
deferred_signal_tid = thread_sp->GetID ();
deferred_signal_thread_sp = thread_sp;
+ // Don't send a stop request to this thread. The thread resume request
+ // above will actually run the step thread, and it will finish the step
+ // by sending a SIGTRAP with the appropriate bits set. So, the deferred
+ // signal call that happens at the end of the loop below needs to let
+ // the pending signal handling to *not* send a stop for this thread here
+ // since the start/stop step functionality will end up with a stop state.
+ // Otherwise, this stepping thread will get sent an erroneous tgkill for
+ // with a SIGSTOP signal.
+ deferred_signal_skip_tid = thread_sp->GetID ();
+
// And the stop signal we should apply for it is a SIGTRAP.
deferred_signo = SIGTRAP;
break;
@@ -2736,13 +2752,17 @@ NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
}
}
- // We don't need to tell the delegate when we're running, so don't do that here.
+ // If we resumed anything, this command was about starting a stopped thread,
+ // not about stopping something that we should trigger later.
+ if (resume_count > 0)
+ return error;
// If we had any thread stopping, then do a deferred notification of the chosen stop thread id and signal
// after all other running threads have stopped.
if (deferred_signal_tid != LLDB_INVALID_THREAD_ID)
{
- CallAfterRunningThreadsStop (deferred_signal_tid,
+ CallAfterRunningThreadsStopWithSkipTID (deferred_signal_tid,
+ deferred_signal_skip_tid,
[=](lldb::tid_t deferred_notification_tid)
{
// Set the signal thread to the current thread.
@@ -3904,5 +3924,20 @@ NativeProcessLinux::CallAfterRunningThreadsStop (lldb::tid_t tid,
},
call_after_function,
CoordinatorErrorHandler);
+}
+void
+NativeProcessLinux::CallAfterRunningThreadsStopWithSkipTID (lldb::tid_t deferred_signal_tid,
+ lldb::tid_t skip_stop_request_tid,
+ const std::function<void (lldb::tid_t tid)> &call_after_function)
+{
+ const lldb::pid_t pid = GetID ();
+ m_coordinator_up->CallAfterRunningThreadsStopWithSkipTIDs (deferred_signal_tid,
+ skip_stop_request_tid != LLDB_INVALID_THREAD_ID ? ThreadStateCoordinator::ThreadIDSet {skip_stop_request_tid} : ThreadStateCoordinator::ThreadIDSet (),
+ [=](lldb::tid_t request_stop_tid)
+ {
+ tgkill (pid, request_stop_tid, SIGSTOP);
+ },
+ call_after_function,
+ CoordinatorErrorHandler);
}
OpenPOWER on IntegriCloud