forked from OSchip/llvm-project
Get initial thread state coordinator integration working.
* Fixed bug in run loop where run loop return enum was being treated erroneously like an int, causing the TSC event loop to terminate prematurely. * Added an explicit scope in NativeProcessLinux::Resume() for the threads lock lifetime. (This was likely unnecessary but is more explicit.) * Fixed a bug in ThreadStateCoordinator where resume execution was not updating the internal state about the thread assumed to be running now. I'll add a test and upstream this in a moment. * Added a verbose logging mechanism to event processing within ThreadStateCoordinator. It is currently enabled when the 'log enable lldb thread' is true upon inferior launch/attach. llvm-svn: 227909
This commit is contained in:
parent
56f981bfce
commit
fa03ad2ebc
File diff suppressed because it is too large
Load Diff
|
@ -31,6 +31,7 @@ namespace lldb_private
|
|||
{
|
||||
class Error;
|
||||
class Module;
|
||||
class ThreadStateCoordinator;
|
||||
class Scalar;
|
||||
|
||||
/// @class NativeProcessLinux
|
||||
|
@ -183,21 +184,12 @@ namespace lldb_private
|
|||
sem_t m_operation_pending;
|
||||
sem_t m_operation_done;
|
||||
|
||||
// Set of tids we're waiting to stop before we notify the delegate of
|
||||
// the stopped state. We only notify the delegate after all threads
|
||||
// ordered to stop have signaled their stop.
|
||||
std::unordered_set<lldb::tid_t> m_wait_for_stop_tids;
|
||||
lldb_private::Mutex m_wait_for_stop_tids_mutex;
|
||||
|
||||
std::unordered_set<lldb::tid_t> m_wait_for_group_stop_tids;
|
||||
lldb::tid_t m_group_stop_signal_tid;
|
||||
int m_group_stop_signal;
|
||||
lldb_private::Mutex m_wait_for_group_stop_tids_mutex;
|
||||
|
||||
lldb_private::LazyBool m_supports_mem_region;
|
||||
std::vector<MemoryRegionInfo> m_mem_region_cache;
|
||||
lldb_private::Mutex m_mem_region_cache_mutex;
|
||||
|
||||
std::unique_ptr<ThreadStateCoordinator> m_coordinator_up;
|
||||
HostThread m_coordinator_thread;
|
||||
|
||||
struct OperationArgs
|
||||
{
|
||||
|
@ -334,6 +326,15 @@ namespace lldb_private
|
|||
void
|
||||
StopOpThread();
|
||||
|
||||
Error
|
||||
StartCoordinatorThread ();
|
||||
|
||||
static void*
|
||||
CoordinatorThread (void *arg);
|
||||
|
||||
void
|
||||
StopCoordinatorThread ();
|
||||
|
||||
/// Stops monitoring the child process thread.
|
||||
void
|
||||
StopMonitor();
|
||||
|
@ -380,16 +381,22 @@ namespace lldb_private
|
|||
bool
|
||||
SingleStep(lldb::tid_t tid, uint32_t signo);
|
||||
|
||||
/// Safely mark all existing threads as waiting for group stop.
|
||||
/// When the final group stop comes in from the set of group stop threads,
|
||||
/// we'll mark the current thread as signaled_thread_tid and set its stop
|
||||
/// reason as the given signo. All other threads from group stop notification
|
||||
/// will have thread stop reason marked as signaled with no signo.
|
||||
// ThreadStateCoordinator helper methods.
|
||||
void
|
||||
SetGroupStopTids (lldb::tid_t signaled_thread_tid, int signo);
|
||||
NotifyThreadCreateStopped (lldb::tid_t tid);
|
||||
|
||||
void
|
||||
OnGroupStop (lldb::tid_t tid);
|
||||
NotifyThreadCreateRunning (lldb::tid_t tid);
|
||||
|
||||
void
|
||||
NotifyThreadDeath (lldb::tid_t tid);
|
||||
|
||||
void
|
||||
NotifyThreadStop (lldb::tid_t tid);
|
||||
|
||||
void
|
||||
CallAfterRunningThreadsStop (lldb::tid_t tid,
|
||||
const std::function<void (lldb::tid_t tid)> &call_after_function);
|
||||
|
||||
lldb_private::Error
|
||||
Detach(lldb::tid_t tid);
|
||||
|
|
|
@ -35,6 +35,9 @@ public:
|
|||
{
|
||||
}
|
||||
|
||||
virtual std::string
|
||||
GetDescription () = 0;
|
||||
|
||||
// Return false if the coordinator should terminate running.
|
||||
virtual EventLoopResult
|
||||
ProcessEvent (ThreadStateCoordinator &coordinator) = 0;
|
||||
|
@ -55,6 +58,12 @@ public:
|
|||
{
|
||||
return eventLoopResultStop;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetDescription () override
|
||||
{
|
||||
return "EventStopCoordinator";
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -190,6 +199,14 @@ public:
|
|||
m_request_thread_stop_function (tid);
|
||||
}
|
||||
|
||||
std::string
|
||||
GetDescription () override
|
||||
{
|
||||
std::ostringstream description;
|
||||
description << "EventCallAfterThreadsStop (triggering_tid=" << m_triggering_tid << ", request_stop_on_all_unstopped_threads=" << m_request_stop_on_all_unstopped_threads << ")";
|
||||
return description.str ();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void
|
||||
|
@ -291,6 +308,12 @@ public:
|
|||
coordinator.ResetNow ();
|
||||
return eventLoopResultContinue;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetDescription () override
|
||||
{
|
||||
return "EventReset";
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -313,6 +336,14 @@ public:
|
|||
return eventLoopResultContinue;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetDescription () override
|
||||
{
|
||||
std::ostringstream description;
|
||||
description << "EventThreadStopped (tid=" << m_tid << ")";
|
||||
return description.str ();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const lldb::tid_t m_tid;
|
||||
|
@ -341,6 +372,14 @@ public:
|
|||
return eventLoopResultContinue;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetDescription () override
|
||||
{
|
||||
std::ostringstream description;
|
||||
description << "EventThreadCreate (tid=" << m_tid << ", " << (m_is_stopped ? "stopped" : "running") << ")";
|
||||
return description.str ();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const lldb::tid_t m_tid;
|
||||
|
@ -368,6 +407,14 @@ public:
|
|||
return eventLoopResultContinue;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetDescription () override
|
||||
{
|
||||
std::ostringstream description;
|
||||
description << "EventThreadDeath (tid=" << m_tid << ")";
|
||||
return description.str ();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const lldb::tid_t m_tid;
|
||||
|
@ -450,6 +497,14 @@ public:
|
|||
return eventLoopResultContinue;
|
||||
}
|
||||
|
||||
std::string
|
||||
GetDescription () override
|
||||
{
|
||||
std::ostringstream description;
|
||||
description << "EventRequestResume (tid=" << m_tid << ")";
|
||||
return description.str ();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const lldb::tid_t m_tid;
|
||||
|
@ -464,7 +519,8 @@ ThreadStateCoordinator::ThreadStateCoordinator (const LogFunction &log_function)
|
|||
m_event_queue (),
|
||||
m_queue_condition (),
|
||||
m_queue_mutex (),
|
||||
m_tid_stop_map ()
|
||||
m_tid_stop_map (),
|
||||
m_log_event_processing (false)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -711,7 +767,39 @@ ThreadStateCoordinator::StopCoordinator ()
|
|||
ThreadStateCoordinator::EventLoopResult
|
||||
ThreadStateCoordinator::ProcessNextEvent ()
|
||||
{
|
||||
return DequeueEventWithWait()->ProcessEvent (*this);
|
||||
// Dequeue the next event, synchronous.
|
||||
if (m_log_event_processing)
|
||||
Log ("ThreadStateCoordinator::%s about to dequeue next event in blocking mode", __FUNCTION__);
|
||||
|
||||
EventBaseSP event_sp = DequeueEventWithWait();
|
||||
assert (event_sp && "event should never be null");
|
||||
if (!event_sp)
|
||||
{
|
||||
Log ("ThreadStateCoordinator::%s error: event_sp was null, signaling exit of event loop.", __FUNCTION__);
|
||||
return eventLoopResultStop;
|
||||
}
|
||||
|
||||
if (m_log_event_processing)
|
||||
{
|
||||
Log ("ThreadStateCoordinator::%s about to process event: %s", __FUNCTION__, event_sp->GetDescription ().c_str ());
|
||||
}
|
||||
|
||||
// Process the event.
|
||||
const EventLoopResult result = event_sp->ProcessEvent (*this);
|
||||
|
||||
if (m_log_event_processing)
|
||||
{
|
||||
Log ("ThreadStateCoordinator::%s event processing returned value %s", __FUNCTION__,
|
||||
result == eventLoopResultContinue ? "eventLoopResultContinue" : "eventLoopResultStop");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
ThreadStateCoordinator::LogEnableEventProcessing (bool enabled)
|
||||
{
|
||||
m_log_event_processing = enabled;
|
||||
}
|
||||
|
||||
ThreadStateCoordinator::EventCallAfterThreadsStop *
|
||||
|
|
|
@ -115,6 +115,10 @@ namespace lldb_private
|
|||
EventLoopResult
|
||||
ProcessNextEvent ();
|
||||
|
||||
// Enable/disable verbose logging of event processing.
|
||||
void
|
||||
LogEnableEventProcessing (bool enabled);
|
||||
|
||||
private:
|
||||
|
||||
// Typedefs.
|
||||
|
@ -179,6 +183,8 @@ namespace lldb_private
|
|||
|
||||
// Maps known TIDs to stop (true) or not-stopped (false) state.
|
||||
TIDBoolMap m_tid_stop_map;
|
||||
|
||||
bool m_log_event_processing;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue