[Lldb-commits] [lldb] r228387 - Fix TestThreadSpecificBreakpoint with LLGS
Tamas Berghammer
tberghammer at google.com
Fri Feb 6 02:42:33 PST 2015
Author: tberghammer
Date: Fri Feb 6 04:42:33 2015
New Revision: 228387
URL: http://llvm.org/viewvc/llvm-project?rev=228387&view=rev
Log:
Fix TestThreadSpecificBreakpoint with LLGS
* Set the state of the process into running/stepping on continue/step operations
* Add mutex to use transactions in Thread State Coordinator
** It is required because the events from two Signal Handler or form a Signal handler and a Resume request shouldn't overlap
* Send Stop Replay Packet only when the state of the process changed
Differential Revision: http://reviews.llvm.org/D7374
Modified:
lldb/trunk/source/Host/common/NativeProcessProtocol.cpp
lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
Modified: lldb/trunk/source/Host/common/NativeProcessProtocol.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/NativeProcessProtocol.cpp?rev=228387&r1=228386&r2=228387&view=diff
==============================================================================
--- lldb/trunk/source/Host/common/NativeProcessProtocol.cpp (original)
+++ lldb/trunk/source/Host/common/NativeProcessProtocol.cpp Fri Feb 6 04:42:33 2015
@@ -402,6 +402,10 @@ void
NativeProcessProtocol::SetState (lldb::StateType state, bool notify_delegates)
{
Mutex::Locker locker (m_state_mutex);
+
+ if (state == m_state)
+ return;
+
m_state = state;
if (StateIsStoppedState (state, false))
Modified: lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp?rev=228387&r1=228386&r2=228387&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Linux/NativeProcessLinux.cpp Fri Feb 6 04:42:33 2015
@@ -1497,8 +1497,6 @@ NativeProcessLinux::Launch(LaunchArgs *a
NativeProcessLinux *monitor = args->m_monitor;
assert (monitor && "monitor is NULL");
- if (!monitor)
- return false;
const char **argv = args->m_argv;
const char **envp = args->m_envp;
@@ -2073,6 +2071,8 @@ NativeProcessLinux::MonitorSIGTRAP(const
if (!info)
return;
+ Mutex::Locker locker (m_threads_mutex);
+
// See if we can find a thread for this signal.
NativeThreadProtocolSP thread_sp = GetThreadByID (pid);
if (!thread_sp)
@@ -2158,45 +2158,41 @@ NativeProcessLinux::MonitorSIGTRAP(const
m_coordinator_up->ResetForExec ();
// Remove all but the main thread here. Linux fork creates a new process which only copies the main thread. Mutexes are in undefined state.
- {
- Mutex::Locker locker (m_threads_mutex);
-
- if (log)
- log->Printf ("NativeProcessLinux::%s exec received, stop tracking all but main thread", __FUNCTION__);
-
- for (auto thread_sp : m_threads)
- {
- const bool is_main_thread = thread_sp && thread_sp->GetID () == GetID ();
- if (is_main_thread)
- {
- main_thread_sp = thread_sp;
- if (log)
- log->Printf ("NativeProcessLinux::%s found main thread with tid %" PRIu64 ", keeping", __FUNCTION__, main_thread_sp->GetID ());
- }
- else
- {
- // Tell thread coordinator this thread is dead.
- if (log)
- log->Printf ("NativeProcessLinux::%s discarding non-main-thread tid %" PRIu64 " due to exec", __FUNCTION__, thread_sp->GetID ());
- }
- }
-
- m_threads.clear ();
+ if (log)
+ log->Printf ("NativeProcessLinux::%s exec received, stop tracking all but main thread", __FUNCTION__);
- if (main_thread_sp)
+ for (auto thread_sp : m_threads)
+ {
+ const bool is_main_thread = thread_sp && thread_sp->GetID () == GetID ();
+ if (is_main_thread)
{
- m_threads.push_back (main_thread_sp);
- SetCurrentThreadID (main_thread_sp->GetID ());
- reinterpret_cast<NativeThreadLinux*>(main_thread_sp.get())->SetStoppedByExec ();
+ main_thread_sp = thread_sp;
+ if (log)
+ log->Printf ("NativeProcessLinux::%s found main thread with tid %" PRIu64 ", keeping", __FUNCTION__, main_thread_sp->GetID ());
}
else
{
- SetCurrentThreadID (LLDB_INVALID_THREAD_ID);
+ // Tell thread coordinator this thread is dead.
if (log)
- log->Printf ("NativeProcessLinux::%s pid %" PRIu64 "no main thread found, discarded all threads, we're in a no-thread state!", __FUNCTION__, GetID ());
+ log->Printf ("NativeProcessLinux::%s discarding non-main-thread tid %" PRIu64 " due to exec", __FUNCTION__, thread_sp->GetID ());
}
}
+ m_threads.clear ();
+
+ if (main_thread_sp)
+ {
+ m_threads.push_back (main_thread_sp);
+ SetCurrentThreadID (main_thread_sp->GetID ());
+ reinterpret_cast<NativeThreadLinux*>(main_thread_sp.get())->SetStoppedByExec ();
+ }
+ else
+ {
+ SetCurrentThreadID (LLDB_INVALID_THREAD_ID);
+ if (log)
+ log->Printf ("NativeProcessLinux::%s pid %" PRIu64 "no main thread found, discarded all threads, we're in a no-thread state!", __FUNCTION__, GetID ());
+ }
+
// Tell coordinator about about the "new" (since exec) stopped main thread.
const lldb::tid_t main_thread_tid = GetID ();
NotifyThreadCreateStopped (main_thread_tid);
@@ -2210,7 +2206,11 @@ NativeProcessLinux::MonitorSIGTRAP(const
assert (main_thread_sp && "exec called during ptraced process but no main thread metadata tracked");
// Let the process know we're stopped.
- SetState (StateType::eStateStopped);
+ CallAfterRunningThreadsStop (pid,
+ [=] (lldb::tid_t signaling_tid)
+ {
+ SetState (StateType::eStateStopped, true);
+ });
break;
}
@@ -2272,7 +2272,11 @@ NativeProcessLinux::MonitorSIGTRAP(const
// once all running threads have checked in as stopped.
SetCurrentThreadID (pid);
// Tell the process we have a stop (from software breakpoint).
- SetState (StateType::eStateStopped, true);
+ CallAfterRunningThreadsStop (pid,
+ [=] (lldb::tid_t signaling_tid)
+ {
+ SetState (StateType::eStateStopped, true);
+ });
break;
case SI_KERNEL:
@@ -2389,6 +2393,8 @@ NativeProcessLinux::MonitorSignal(const
//
// Similarly, ACK signals generated by this monitor.
+ Mutex::Locker locker (m_threads_mutex);
+
// See if we can find a thread for this signal.
NativeThreadProtocolSP thread_sp = GetThreadByID (pid);
if (!thread_sp)
@@ -2565,8 +2571,6 @@ NativeProcessLinux::MonitorSignal(const
Error
NativeProcessLinux::Resume (const ResumeActionList &resume_actions)
{
- Error error;
-
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS | LIBLLDB_LOG_THREAD));
if (log)
log->Printf ("NativeProcessLinux::%s called: pid %" PRIu64, __FUNCTION__, GetID ());
@@ -2575,85 +2579,83 @@ NativeProcessLinux::Resume (const Resume
lldb::tid_t deferred_signal_skip_tid = LLDB_INVALID_THREAD_ID;
int deferred_signo = 0;
NativeThreadProtocolSP deferred_signal_thread_sp;
- int resume_count = 0;
bool stepping = false;
+ Mutex::Locker locker (m_threads_mutex);
- // std::vector<NativeThreadProtocolSP> new_stop_threads;
-
- // Scope for threads mutex.
+ for (auto thread_sp : m_threads)
{
- Mutex::Locker locker (m_threads_mutex);
- for (auto thread_sp : m_threads)
- {
- assert (thread_sp && "thread list should not contain NULL threads");
-
- const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true);
+ assert (thread_sp && "thread list should not contain NULL threads");
- if (action == nullptr)
- {
- if (log)
- log->Printf ("NativeProcessLinux::%s no action specified for pid %" PRIu64 " tid %" PRIu64,
- __FUNCTION__, GetID (), thread_sp->GetID ());
- continue;
- }
+ const ResumeAction *const action = resume_actions.GetActionForThread (thread_sp->GetID (), true);
+ if (action == nullptr)
+ {
if (log)
- {
- log->Printf ("NativeProcessLinux::%s processing resume action state %s for pid %" PRIu64 " tid %" PRIu64,
- __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
- }
+ log->Printf ("NativeProcessLinux::%s no action specified for pid %" PRIu64 " tid %" PRIu64,
+ __FUNCTION__, GetID (), thread_sp->GetID ());
+ continue;
+ }
- switch (action->state)
- {
- case eStateRunning:
- {
- // Run the thread, possibly feeding it the signal.
- const int signo = action->signal;
- m_coordinator_up->RequestThreadResumeAsNeeded (thread_sp->GetID (),
- [=](lldb::tid_t tid_to_resume, bool supress_signal)
- {
- reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetRunning ();
- // Pass this signal number on to the inferior to handle.
- return Resume (tid_to_resume, (signo > 0 && !supress_signal) ? signo : LLDB_INVALID_SIGNAL_NUMBER);
- },
- CoordinatorErrorHandler);
- ++resume_count;
- break;
- }
+ if (log)
+ {
+ log->Printf ("NativeProcessLinux::%s processing resume action state %s for pid %" PRIu64 " tid %" PRIu64,
+ __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
+ }
+
+ switch (action->state)
+ {
+ case eStateRunning:
+ {
+ // Run the thread, possibly feeding it the signal.
+ const int signo = action->signal;
+ m_coordinator_up->RequestThreadResumeAsNeeded (thread_sp->GetID (),
+ [=](lldb::tid_t tid_to_resume, bool supress_signal)
+ {
+ reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetRunning ();
+ // Pass this signal number on to the inferior to handle.
+ const auto resume_result = Resume (tid_to_resume, (signo > 0 && !supress_signal) ? signo : LLDB_INVALID_SIGNAL_NUMBER);
+ if (resume_result.Success())
+ SetState(eStateRunning, true);
+ return resume_result;
+ },
+ CoordinatorErrorHandler);
+ break;
+ }
+
+ case eStateStepping:
+ {
+ // Request the step.
+ const int signo = action->signal;
+ m_coordinator_up->RequestThreadResume (thread_sp->GetID (),
+ [=](lldb::tid_t tid_to_step, bool supress_signal)
+ {
+ reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStepping ();
+ const auto step_result = SingleStep (tid_to_step,(signo > 0 && !supress_signal) ? signo : LLDB_INVALID_SIGNAL_NUMBER);
+ assert (step_result.Success() && "SingleStep() failed");
+ if (step_result.Success())
+ SetState(eStateStepping, true);
+ return step_result;
+ },
+ CoordinatorErrorHandler);
+ stepping = true;
+ break;
+ }
- case eStateStepping:
+ case eStateSuspended:
+ case eStateStopped:
+ // if we haven't chosen a deferred signal tid yet, use this one.
+ if (deferred_signal_tid == LLDB_INVALID_THREAD_ID)
{
- // Request the step.
- const int signo = action->signal;
- m_coordinator_up->RequestThreadResume (thread_sp->GetID (),
- [=](lldb::tid_t tid_to_step, bool supress_signal)
- {
- reinterpret_cast<NativeThreadLinux*> (thread_sp.get ())->SetStepping ();
- const auto step_result = SingleStep (tid_to_step,(signo > 0 && !supress_signal) ? signo : LLDB_INVALID_SIGNAL_NUMBER);
- assert (step_result.Success() && "SingleStep() failed");
- return step_result;
- },
- CoordinatorErrorHandler);
- stepping = true;
- break;
+ deferred_signal_tid = thread_sp->GetID ();
+ deferred_signal_thread_sp = thread_sp;
+ deferred_signo = SIGSTOP;
}
+ break;
- case eStateSuspended:
- case eStateStopped:
- // if we haven't chosen a deferred signal tid yet, use this one.
- if (deferred_signal_tid == LLDB_INVALID_THREAD_ID)
- {
- deferred_signal_tid = thread_sp->GetID ();
- deferred_signal_thread_sp = thread_sp;
- deferred_signo = SIGSTOP;
- }
- break;
-
- default:
- return Error ("NativeProcessLinux::%s (): unexpected state %s specified for pid %" PRIu64 ", tid %" PRIu64,
- __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
- }
+ default:
+ return Error ("NativeProcessLinux::%s (): unexpected state %s specified for pid %" PRIu64 ", tid %" PRIu64,
+ __FUNCTION__, StateAsCString (action->state), GetID (), thread_sp->GetID ());
}
}
@@ -2677,7 +2679,7 @@ NativeProcessLinux::Resume (const Resume
});
}
- return error;
+ return Error();
}
Error
@@ -2728,47 +2730,44 @@ NativeProcessLinux::Interrupt ()
{
// Pick a running thread (or if none, a not-dead stopped thread) as
// the chosen thread that will be the stop-reason thread.
- Error error;
Log *log (GetLogIfAllCategoriesSet (LIBLLDB_LOG_PROCESS));
NativeThreadProtocolSP running_thread_sp;
NativeThreadProtocolSP stopped_thread_sp;
- {
- Mutex::Locker locker (m_threads_mutex);
+
+ if (log)
+ log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__);
- if (log)
- log->Printf ("NativeProcessLinux::%s selecting running thread for interrupt target", __FUNCTION__);
+ Mutex::Locker locker (m_threads_mutex);
- for (auto thread_sp : m_threads)
+ for (auto thread_sp : m_threads)
+ {
+ // The thread shouldn't be null but lets just cover that here.
+ if (!thread_sp)
+ continue;
+
+ // If we have a running or stepping thread, we'll call that the
+ // target of the interrupt.
+ const auto thread_state = thread_sp->GetState ();
+ if (thread_state == eStateRunning ||
+ thread_state == eStateStepping)
{
- // The thread shouldn't be null but lets just cover that here.
- if (!thread_sp)
- continue;
-
- // If we have a running or stepping thread, we'll call that the
- // target of the interrupt.
- const auto thread_state = thread_sp->GetState ();
- if (thread_state == eStateRunning ||
- thread_state == eStateStepping)
- {
- running_thread_sp = thread_sp;
- break;
- }
- else if (!stopped_thread_sp && StateIsStoppedState (thread_state, true))
- {
- // Remember the first non-dead stopped thread. We'll use that as a backup if there are no running threads.
- stopped_thread_sp = thread_sp;
- }
+ running_thread_sp = thread_sp;
+ break;
+ }
+ else if (!stopped_thread_sp && StateIsStoppedState (thread_state, true))
+ {
+ // Remember the first non-dead stopped thread. We'll use that as a backup if there are no running threads.
+ stopped_thread_sp = thread_sp;
}
}
if (!running_thread_sp && !stopped_thread_sp)
{
- error.SetErrorString ("found no running/stepping or live stopped threads as target for interrupt");
+ Error error("found no running/stepping or live stopped threads as target for interrupt");
if (log)
- {
log->Printf ("NativeProcessLinux::%s skipping due to error: %s", __FUNCTION__, error.AsCString ());
- }
+
return error;
}
@@ -2790,10 +2789,10 @@ NativeProcessLinux::Interrupt ()
// Set the thread state as stopped by the deferred signo.
reinterpret_cast<NativeThreadLinux*> (deferred_signal_thread_sp.get ())->SetStoppedBySignal (SIGSTOP);
- // Tell the process delegate that the process is in a stopped state.
- SetState (StateType::eStateStopped, true);
- });
- return error;
+ // Tell the process delegate that the process is in a stopped state.
+ SetState (StateType::eStateStopped, true);
+ });
+ return Error();
}
Error
More information about the lldb-commits
mailing list