[Lldb-commits] [lldb] r218833 - thread state coordinator: added error callbacks, cleaned up tests.

Eric Christopher echristo at gmail.com
Wed Oct 1 18:04:25 PDT 2014


> +        // Validate we know about the deferred trigger thread.
> +        if (auto find_it = coordinator.m_tid_stop_map.find (m_triggering_tid) == coordinator.m_tid_stop_map.end ())
> +        {

find_it is unused here :)

I've removed it in r218844.

-eric

> +            // We don't know about this thread.  This is an error condition.
> +            std::ostringstream error_message;
> +            error_message << "error: deferred notification tid " << m_triggering_tid << " is unknown";
> +            m_error_function (error_message.str ());
> +
> +            // We bail out here.
> +            return eventLoopResultContinue;
> +        }
> +
>          // Request a stop for all the thread stops that need to be stopped
>          // and are not already known to be stopped.  Keep a list of all the
>          // threads from which we still need to hear a stop reply.
> @@ -108,10 +123,24 @@ public:
>          ThreadIDSet sent_tids;
>          for (auto tid : m_wait_for_stop_tids)
>          {
> -            // If we don't know about the thread's stop state or we
> -            // know it is not stopped, we need to send it a stop request.
> +            // Validate we know about all tids for which we must first receive a stop before
> +            // triggering the deferred stop notification.
>              auto find_it = coordinator.m_tid_stop_map.find (tid);
> -            if ((find_it == coordinator.m_tid_stop_map.end ()) || !find_it->second)
> +            if (find_it == coordinator.m_tid_stop_map.end ())
> +            {
> +                // This is an error.  We shouldn't be asking for waiting pids that aren't known.
> +                // NOTE: we may be stripping out the specification of wait tids and handle this
> +                // automatically, in which case this state can never occur.
> +                std::ostringstream error_message;
> +                error_message << "error: deferred notification for tid " << m_triggering_tid << " specified an unknown/untracked pending stop tid " << m_triggering_tid;
> +                m_error_function (error_message.str ());
> +
> +                // Bail out here.
> +                return eventLoopResultContinue;
> +            }
> +
> +            // If the pending stop thread is currently running, we need to send it a stop request.
> +            if (!find_it->second)
>              {
>                  m_request_thread_stop_function (tid);
>                  sent_tids.insert (tid);
> @@ -137,7 +166,7 @@ public:
>              coordinator.SetPendingNotification (shared_from_this ());
>          }
>
> -        return true;
> +        return eventLoopResultContinue;
>      }
>
>      // Return true if still pending thread stops waiting; false if no more stops.
> @@ -184,6 +213,7 @@ private:
>      const ThreadIDSet m_original_wait_for_stop_tids;
>      ThreadIDFunction m_request_thread_stop_function;
>      ThreadIDFunction m_call_after_function;
> +    ErrorFunction m_error_function;
>  };
>
>  //===----------------------------------------------------------------------===//
> @@ -196,11 +226,11 @@ public:
>      {
>      }
>
> -    bool
> +    EventLoopResult
>      ProcessEvent(ThreadStateCoordinator &coordinator) override
>      {
>          coordinator.ResetNow ();
> -        return true;
> +        return eventLoopResultContinue;
>      }
>  };
>
> @@ -209,22 +239,25 @@ public:
>  class ThreadStateCoordinator::EventThreadStopped : public ThreadStateCoordinator::EventBase
>  {
>  public:
> -    EventThreadStopped (lldb::tid_t tid):
> +    EventThreadStopped (lldb::tid_t tid,
> +                        const ErrorFunction &error_function):
>      EventBase (),
> -    m_tid (tid)
> +    m_tid (tid),
> +    m_error_function (error_function)
>      {
>      }
>
> -    bool
> +    EventLoopResult
>      ProcessEvent(ThreadStateCoordinator &coordinator) override
>      {
> -        coordinator.ThreadDidStop (m_tid);
> -        return true;
> +        coordinator.ThreadDidStop (m_tid, m_error_function);
> +        return eventLoopResultContinue;
>      }
>
>  private:
>
>      const lldb::tid_t m_tid;
> +    ErrorFunction m_error_function;
>  };
>
>  //===----------------------------------------------------------------------===//
> @@ -232,22 +265,28 @@ private:
>  class ThreadStateCoordinator::EventThreadCreate : public ThreadStateCoordinator::EventBase
>  {
>  public:
> -    EventThreadCreate (lldb::tid_t tid):
> +    EventThreadCreate (lldb::tid_t tid,
> +                       bool is_stopped,
> +                       const ErrorFunction &error_function):
>      EventBase (),
> -    m_tid (tid)
> +    m_tid (tid),
> +    m_is_stopped (is_stopped),
> +    m_error_function (error_function)
>      {
>      }
>
> -    bool
> +    EventLoopResult
>      ProcessEvent(ThreadStateCoordinator &coordinator) override
>      {
> -        coordinator.ThreadWasCreated (m_tid);
> -        return true;
> +        coordinator.ThreadWasCreated (m_tid, m_is_stopped);
> +        return eventLoopResultContinue;
>      }
>
>  private:
>
>      const lldb::tid_t m_tid;
> +    const bool m_is_stopped;
> +    ErrorFunction m_error_function;
>  };
>
>  //===----------------------------------------------------------------------===//
> @@ -255,22 +294,25 @@ private:
>  class ThreadStateCoordinator::EventThreadDeath : public ThreadStateCoordinator::EventBase
>  {
>  public:
> -    EventThreadDeath (lldb::tid_t tid):
> +    EventThreadDeath (lldb::tid_t tid,
> +                      const ErrorFunction &error_function):
>      EventBase (),
> -    m_tid (tid)
> +    m_tid (tid),
> +    m_error_function (error_function)
>      {
>      }
>
> -    bool
> +    EventLoopResult
>      ProcessEvent(ThreadStateCoordinator &coordinator) override
>      {
>          coordinator.ThreadDidDie (m_tid);
> -        return true;
> +        return eventLoopResultContinue;
>      }
>
>  private:
>
>      const lldb::tid_t m_tid;
> +    ErrorFunction m_error_function;
>  };
>
>  //===----------------------------------------------------------------------===//
> @@ -278,14 +320,17 @@ private:
>  class ThreadStateCoordinator::EventRequestResume : public ThreadStateCoordinator::EventBase
>  {
>  public:
> -    EventRequestResume (lldb::tid_t tid, const ThreadIDFunction &request_thread_resume_function):
> +    EventRequestResume (lldb::tid_t tid,
> +                        const ThreadIDFunction &request_thread_resume_function,
> +                        const ErrorFunction &error_function):
>      EventBase (),
>      m_tid (tid),
> -    m_request_thread_resume_function (request_thread_resume_function)
> +    m_request_thread_resume_function (request_thread_resume_function),
> +    m_error_function (error_function)
>      {
>      }
>
> -    bool
> +    EventLoopResult
>      ProcessEvent(ThreadStateCoordinator &coordinator) override
>      {
>          // Tell the thread to resume if we don't already think it is running.
> @@ -294,13 +339,13 @@ public:
>          {
>              // Skip the resume call - we think it is already running because we don't know anything about the thread.
>              coordinator.Log ("EventRequestResume::%s skipping resume request because we don't know about tid %" PRIu64 " and we therefore assume it is running.", __FUNCTION__, m_tid);
> -            return true;
> +            return eventLoopResultContinue;
>          }
>          else if (!find_it->second)
>          {
>              // Skip the resume call - we have tracked it to be running.
>              coordinator.Log ("EventRequestResume::%s skipping resume request because tid %" PRIu64 " is already running according to our state tracking.", __FUNCTION__, m_tid);
> -            return true;
> +            return eventLoopResultContinue;
>          }
>
>          // Before we do the resume below, first check if we have a pending
> @@ -333,13 +378,14 @@ public:
>          // to reflect it is running after this completes.
>          m_request_thread_resume_function (m_tid);
>
> -        return true;
> +        return eventLoopResultContinue;
>      }
>
>  private:
>
>      const lldb::tid_t m_tid;
>      ThreadIDFunction m_request_thread_resume_function;
> +    ErrorFunction m_error_function;
>  };
>
>  //===----------------------------------------------------------------------===//
> @@ -403,19 +449,32 @@ void
>  ThreadStateCoordinator::CallAfterThreadsStop (const lldb::tid_t triggering_tid,
>                                                const ThreadIDSet &wait_for_stop_tids,
>                                                const ThreadIDFunction &request_thread_stop_function,
> -                                              const ThreadIDFunction &call_after_function)
> +                                              const ThreadIDFunction &call_after_function,
> +                                              const ErrorFunction &error_function)
>  {
>      EnqueueEvent (EventBaseSP (new EventCallAfterThreadsStop (triggering_tid,
>                                                                wait_for_stop_tids,
>                                                                request_thread_stop_function,
> -                                                              call_after_function)));
> +                                                              call_after_function,
> +                                                              error_function)));
>  }
>
>  void
> -ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid)
> +ThreadStateCoordinator::ThreadDidStop (lldb::tid_t tid, ErrorFunction &error_function)
>  {
> +    // Ensure we know about the thread.
> +    auto find_it = m_tid_stop_map.find (tid);
> +    if (find_it == m_tid_stop_map.end ())
> +    {
> +        // We don't know about this thread.  This is an error condition.
> +        std::ostringstream error_message;
> +        error_message << "error: tid " << tid << " asked to stop but tid is unknown";
> +        error_function (error_message.str ());
> +        return;
> +    }
> +
>      // Update the global list of known thread states.  This one is definitely stopped.
> -    m_tid_stop_map[tid] = true;
> +    find_it->second = true;
>
>      // If we have a pending notification, remove this from the set.
>      EventCallAfterThreadsStop *const call_after_event = GetPendingThreadStopNotification ();
> @@ -431,14 +490,13 @@ ThreadStateCoordinator::ThreadDidStop (l
>  }
>
>  void
> -ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid)
> +ThreadStateCoordinator::ThreadWasCreated (lldb::tid_t tid, bool is_stopped)
>  {
>      // Add the new thread to the stop map.
> -    // We assume a created thread is not stopped.
> -    m_tid_stop_map[tid] = false;
> +    m_tid_stop_map[tid] = is_stopped;
>
>      EventCallAfterThreadsStop *const call_after_event = GetPendingThreadStopNotification ();
> -    if (call_after_event)
> +    if (call_after_event && !is_stopped)
>      {
>          // Tell the pending notification that we need to wait
>          // for this new thread to stop.
> @@ -492,27 +550,33 @@ ThreadStateCoordinator::Log (const char
>  }
>
>  void
> -ThreadStateCoordinator::NotifyThreadStop (lldb::tid_t tid)
> +ThreadStateCoordinator::NotifyThreadStop (lldb::tid_t tid,
> +                                          const ErrorFunction &error_function)
>  {
> -    EnqueueEvent (EventBaseSP (new EventThreadStopped (tid)));
> +    EnqueueEvent (EventBaseSP (new EventThreadStopped (tid, error_function)));
>  }
>
>  void
> -ThreadStateCoordinator::RequestThreadResume (lldb::tid_t tid, const ThreadIDFunction &request_thread_resume_function)
> +ThreadStateCoordinator::RequestThreadResume (lldb::tid_t tid,
> +                                             const ThreadIDFunction &request_thread_resume_function,
> +                                             const ErrorFunction &error_function)
>  {
> -    EnqueueEvent (EventBaseSP (new EventRequestResume (tid, request_thread_resume_function)));
> +    EnqueueEvent (EventBaseSP (new EventRequestResume (tid, request_thread_resume_function, error_function)));
>  }
>
>  void
> -ThreadStateCoordinator::NotifyThreadCreate (lldb::tid_t tid)
> +ThreadStateCoordinator::NotifyThreadCreate (lldb::tid_t tid,
> +                                            bool is_stopped,
> +                                            const ErrorFunction &error_function)
>  {
> -    EnqueueEvent (EventBaseSP (new EventThreadCreate (tid)));
> +    EnqueueEvent (EventBaseSP (new EventThreadCreate (tid, is_stopped, error_function)));
>  }
>
>  void
> -ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid)
> +ThreadStateCoordinator::NotifyThreadDeath (lldb::tid_t tid,
> +                                           const ErrorFunction &error_function)
>  {
> -    EnqueueEvent (EventBaseSP (new EventThreadDeath (tid)));
> +    EnqueueEvent (EventBaseSP (new EventThreadDeath (tid, error_function)));
>  }
>
>  void
> @@ -541,7 +605,7 @@ ThreadStateCoordinator::StopCoordinator
>      EnqueueEvent (EventBaseSP (new EventStopCoordinator ()));
>  }
>
> -bool
> +ThreadStateCoordinator::EventLoopResult
>  ThreadStateCoordinator::ProcessNextEvent ()
>  {
>      return DequeueEventWithWait()->ProcessEvent (*this);
>
> Modified: lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h
> URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h?rev=218833&r1=218832&r2=218833&view=diff
> ==============================================================================
> --- lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h (original)
> +++ lldb/trunk/source/Plugins/Process/Linux/ThreadStateCoordinator.h Wed Oct  1 16:40:45 2014
> @@ -28,36 +28,62 @@ namespace lldb_private
>          // Typedefs.
>          typedef std::unordered_set<lldb::tid_t> ThreadIDSet;
>
> -        // Protocols.
> -
> +        enum EventLoopResult
> +        {
> +            eventLoopResultContinue,
> +            eventLoopResultStop
> +        };
>
>          // Callback/block definitions.
>          typedef std::function<void (lldb::tid_t tid)> ThreadIDFunction;
>          typedef std::function<void (const char *format, va_list args)> LogFunction;
> +        typedef std::function<void (const std::string &error_message)> ErrorFunction;
>
> -        // constructors
> +        // Constructors.
>          ThreadStateCoordinator (const LogFunction &log_function);
>
> -        // The main purpose of the class: triggering an action after
> -        // a given set of threads stop.
> +        // Notify the coordinator when a thread is created and/or starting to be
> +        // tracked.  is_stopped should be true if the thread is currently stopped;
> +        // otherwise, it should be set false if it is already running.  Will
> +        // call the error function if the thread id is already tracked.
> +        void
> +        NotifyThreadCreate (lldb::tid_t tid,
> +                            bool is_stopped,
> +                            const ErrorFunction &error_function);
> +
> +        // Notify the coordinator when a previously-existing thread should no
> +        // longer be tracked.  The error_function will trigger if the thread
> +        // is not being tracked.
> +        void
> +        NotifyThreadDeath (lldb::tid_t tid,
> +                           const ErrorFunction &error_function);
> +
> +
> +        // This method is the main purpose of the class: triggering a deferred
> +        // action after a given set of threads stop.  The triggering_tid is the
> +        // thread id passed to the call_after_function.  The error_function will
> +        // be fired if either the triggering tid or any of the wait_for_stop_tids
> +        // are unknown at the time the method is processed.
>          void
>          CallAfterThreadsStop (lldb::tid_t triggering_tid,
>                                const ThreadIDSet &wait_for_stop_tids,
>                                const ThreadIDFunction &request_thread_stop_function,
> -                              const ThreadIDFunction &call_after_function);
> -
> -        // Notifications called when various state changes occur.
> -        void
> -        NotifyThreadStop (lldb::tid_t tid);
> +                              const ThreadIDFunction &call_after_function,
> +                              const ErrorFunction &error_function);
>
> +        // Notify the thread stopped.  Will trigger error at time of execution if we
> +        // already think it is stopped.
>          void
> -        RequestThreadResume (lldb::tid_t tid, const ThreadIDFunction &request_thread_resume_func);
> +        NotifyThreadStop (lldb::tid_t tid,
> +                          const ErrorFunction &error_function);
>
> -        void
> -        NotifyThreadCreate (lldb::tid_t tid);
> -
> -        void
> -        NotifyThreadDeath (lldb::tid_t tid);
> +        // Request that the given thread id should have the request_thread_resume_function
> +        // called.  Will trigger the error_function if the thread is thought to be running
> +        // already at that point.
> +        void
> +        RequestThreadResume (lldb::tid_t tid,
> +                             const ThreadIDFunction &request_thread_resume_function,
> +                             const ErrorFunction &error_function);
>
>          // Indicate the calling process did an exec and that the thread state
>          // should be 100% cleared.
> @@ -76,7 +102,7 @@ namespace lldb_private
>          // Expected usage is to run this in a separate thread until the function
>          // returns false.  Always call this from the same thread.  The processing
>          // logic assumes the execution of this is implicitly serialized.
> -        bool
> +        EventLoopResult
>          ProcessNextEvent ();
>
>      private:
> @@ -111,10 +137,10 @@ namespace lldb_private
>          SetPendingNotification (const EventBaseSP &event_sp);
>
>          void
> -        ThreadDidStop (lldb::tid_t tid);
> +        ThreadDidStop (lldb::tid_t tid, ErrorFunction &error_function);
>
>          void
> -        ThreadWasCreated (lldb::tid_t tid);
> +        ThreadWasCreated (lldb::tid_t tid, bool is_stopped);
>
>          void
>          ThreadDidDie (lldb::tid_t tid);
>
>
> _______________________________________________
> lldb-commits mailing list
> lldb-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits



More information about the lldb-commits mailing list