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:
Chaoren Lin 2015-02-03 01:50:42 +00:00
parent 56f981bfce
commit fa03ad2ebc
4 changed files with 560 additions and 425 deletions

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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 *

View File

@ -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;
}; };
} }