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 Error;
|
||||||
class Module;
|
class Module;
|
||||||
|
class ThreadStateCoordinator;
|
||||||
class Scalar;
|
class Scalar;
|
||||||
|
|
||||||
/// @class NativeProcessLinux
|
/// @class NativeProcessLinux
|
||||||
|
@ -183,21 +184,12 @@ namespace lldb_private
|
||||||
sem_t m_operation_pending;
|
sem_t m_operation_pending;
|
||||||
sem_t m_operation_done;
|
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;
|
lldb_private::LazyBool m_supports_mem_region;
|
||||||
std::vector<MemoryRegionInfo> m_mem_region_cache;
|
std::vector<MemoryRegionInfo> m_mem_region_cache;
|
||||||
lldb_private::Mutex m_mem_region_cache_mutex;
|
lldb_private::Mutex m_mem_region_cache_mutex;
|
||||||
|
|
||||||
|
std::unique_ptr<ThreadStateCoordinator> m_coordinator_up;
|
||||||
|
HostThread m_coordinator_thread;
|
||||||
|
|
||||||
struct OperationArgs
|
struct OperationArgs
|
||||||
{
|
{
|
||||||
|
@ -334,6 +326,15 @@ namespace lldb_private
|
||||||
void
|
void
|
||||||
StopOpThread();
|
StopOpThread();
|
||||||
|
|
||||||
|
Error
|
||||||
|
StartCoordinatorThread ();
|
||||||
|
|
||||||
|
static void*
|
||||||
|
CoordinatorThread (void *arg);
|
||||||
|
|
||||||
|
void
|
||||||
|
StopCoordinatorThread ();
|
||||||
|
|
||||||
/// Stops monitoring the child process thread.
|
/// Stops monitoring the child process thread.
|
||||||
void
|
void
|
||||||
StopMonitor();
|
StopMonitor();
|
||||||
|
@ -380,16 +381,22 @@ namespace lldb_private
|
||||||
bool
|
bool
|
||||||
SingleStep(lldb::tid_t tid, uint32_t signo);
|
SingleStep(lldb::tid_t tid, uint32_t signo);
|
||||||
|
|
||||||
/// Safely mark all existing threads as waiting for group stop.
|
// ThreadStateCoordinator helper methods.
|
||||||
/// 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.
|
|
||||||
void
|
void
|
||||||
SetGroupStopTids (lldb::tid_t signaled_thread_tid, int signo);
|
NotifyThreadCreateStopped (lldb::tid_t tid);
|
||||||
|
|
||||||
void
|
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
|
lldb_private::Error
|
||||||
Detach(lldb::tid_t tid);
|
Detach(lldb::tid_t tid);
|
||||||
|
|
|
@ -35,6 +35,9 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual std::string
|
||||||
|
GetDescription () = 0;
|
||||||
|
|
||||||
// Return false if the coordinator should terminate running.
|
// Return false if the coordinator should terminate running.
|
||||||
virtual EventLoopResult
|
virtual EventLoopResult
|
||||||
ProcessEvent (ThreadStateCoordinator &coordinator) = 0;
|
ProcessEvent (ThreadStateCoordinator &coordinator) = 0;
|
||||||
|
@ -55,6 +58,12 @@ public:
|
||||||
{
|
{
|
||||||
return eventLoopResultStop;
|
return eventLoopResultStop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GetDescription () override
|
||||||
|
{
|
||||||
|
return "EventStopCoordinator";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -190,6 +199,14 @@ public:
|
||||||
m_request_thread_stop_function (tid);
|
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:
|
private:
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -291,6 +308,12 @@ public:
|
||||||
coordinator.ResetNow ();
|
coordinator.ResetNow ();
|
||||||
return eventLoopResultContinue;
|
return eventLoopResultContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GetDescription () override
|
||||||
|
{
|
||||||
|
return "EventReset";
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
@ -313,6 +336,14 @@ public:
|
||||||
return eventLoopResultContinue;
|
return eventLoopResultContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GetDescription () override
|
||||||
|
{
|
||||||
|
std::ostringstream description;
|
||||||
|
description << "EventThreadStopped (tid=" << m_tid << ")";
|
||||||
|
return description.str ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const lldb::tid_t m_tid;
|
const lldb::tid_t m_tid;
|
||||||
|
@ -341,6 +372,14 @@ public:
|
||||||
return eventLoopResultContinue;
|
return eventLoopResultContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GetDescription () override
|
||||||
|
{
|
||||||
|
std::ostringstream description;
|
||||||
|
description << "EventThreadCreate (tid=" << m_tid << ", " << (m_is_stopped ? "stopped" : "running") << ")";
|
||||||
|
return description.str ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const lldb::tid_t m_tid;
|
const lldb::tid_t m_tid;
|
||||||
|
@ -368,6 +407,14 @@ public:
|
||||||
return eventLoopResultContinue;
|
return eventLoopResultContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GetDescription () override
|
||||||
|
{
|
||||||
|
std::ostringstream description;
|
||||||
|
description << "EventThreadDeath (tid=" << m_tid << ")";
|
||||||
|
return description.str ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const lldb::tid_t m_tid;
|
const lldb::tid_t m_tid;
|
||||||
|
@ -450,6 +497,14 @@ public:
|
||||||
return eventLoopResultContinue;
|
return eventLoopResultContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
GetDescription () override
|
||||||
|
{
|
||||||
|
std::ostringstream description;
|
||||||
|
description << "EventRequestResume (tid=" << m_tid << ")";
|
||||||
|
return description.str ();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
const lldb::tid_t m_tid;
|
const lldb::tid_t m_tid;
|
||||||
|
@ -464,7 +519,8 @@ ThreadStateCoordinator::ThreadStateCoordinator (const LogFunction &log_function)
|
||||||
m_event_queue (),
|
m_event_queue (),
|
||||||
m_queue_condition (),
|
m_queue_condition (),
|
||||||
m_queue_mutex (),
|
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::EventLoopResult
|
||||||
ThreadStateCoordinator::ProcessNextEvent ()
|
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 *
|
ThreadStateCoordinator::EventCallAfterThreadsStop *
|
||||||
|
|
|
@ -115,6 +115,10 @@ namespace lldb_private
|
||||||
EventLoopResult
|
EventLoopResult
|
||||||
ProcessNextEvent ();
|
ProcessNextEvent ();
|
||||||
|
|
||||||
|
// Enable/disable verbose logging of event processing.
|
||||||
|
void
|
||||||
|
LogEnableEventProcessing (bool enabled);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// Typedefs.
|
// Typedefs.
|
||||||
|
@ -179,6 +183,8 @@ namespace lldb_private
|
||||||
|
|
||||||
// Maps known TIDs to stop (true) or not-stopped (false) state.
|
// Maps known TIDs to stop (true) or not-stopped (false) state.
|
||||||
TIDBoolMap m_tid_stop_map;
|
TIDBoolMap m_tid_stop_map;
|
||||||
|
|
||||||
|
bool m_log_event_processing;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue