diff options
author | Chaoren Lin <chaorenl@google.com> | 2015-02-03 01:50:49 +0000 |
---|---|---|
committer | Chaoren Lin <chaorenl@google.com> | 2015-02-03 01:50:49 +0000 |
commit | 03f12d6b224cb6691a4fee4e08adc156a3a8fd28 (patch) | |
tree | 4366c7eec81220240dd11b201729b8b078c39590 /lldb/source/Plugins/Process/Linux/NativeProcessLinux.cpp | |
parent | ae29d39570cacf4c82590162a26d89bacbb6d8d3 (diff) | |
download | bcm5719-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.cpp | 47 |
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); } |