Commit 221d51cf authored by Jim Ingham's avatar Jim Ingham
Browse files

Figure out the reply to "PlanExplainsStop" once when we stop and then use the cached

value.  This fixes problems, for instance, with the StepRange plans, where they know that
they explained the stop because they were at their "run to here" breakpoint, then deleted
that breakpoint, so when they got asked again, doh!  I had done this for a couple of plans
in an ad hoc fashion, this just formalizes it.

Also add a "ResumeRequested" in Process so that the code in the completion handlers can
tell the ShouldStop logic they want to resume rather than just directly resuming.  That allows 
us to handle resuming in a more controlled fashion.

Also, SetPublicState can take a "restarted" flag, so that it doesn't drop the run lock when
the target was immediately restarted.
--This line, and those below , will be ignored--

M    test/lang/objc/objc-dynamic-value/TestObjCDynamicValue.py
M    include/lldb/Target/ThreadList.h
M    include/lldb/Target/ThreadPlanStepOut.h
M    include/lldb/Target/Thread.h
M    include/lldb/Target/ThreadPlanBase.h
M    include/lldb/Target/ThreadPlanStepThrough.h
M    include/lldb/Target/ThreadPlanStepInstruction.h
M    include/lldb/Target/ThreadPlanStepInRange.h
M    include/lldb/Target/ThreadPlanStepOverBreakpoint.h
M    include/lldb/Target/ThreadPlanStepUntil.h
M    include/lldb/Target/StopInfo.h
M    include/lldb/Target/Process.h
M    include/lldb/Target/ThreadPlanRunToAddress.h
M    include/lldb/Target/ThreadPlan.h
M    include/lldb/Target/ThreadPlanCallFunction.h
M    include/lldb/Target/ThreadPlanStepOverRange.h
M    source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.h
M    source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleThreadPlanStepThroughObjCTrampoline.cpp
M    source/Target/StopInfo.cpp
M    source/Target/Process.cpp
M    source/Target/ThreadPlanRunToAddress.cpp
M    source/Target/ThreadPlan.cpp
M    source/Target/ThreadPlanCallFunction.cpp
M    source/Target/ThreadPlanStepOverRange.cpp
M    source/Target/ThreadList.cpp
M    source/Target/ThreadPlanStepOut.cpp
M    source/Target/Thread.cpp
M    source/Target/ThreadPlanBase.cpp
M    source/Target/ThreadPlanStepThrough.cpp
M    source/Target/ThreadPlanStepInstruction.cpp
M    source/Target/ThreadPlanStepInRange.cpp
M    source/Target/ThreadPlanStepOverBreakpoint.cpp
M    source/Target/ThreadPlanStepUntil.cpp
M    lldb.xcodeproj/xcshareddata/xcschemes/Run Testsuite.xcscheme

llvm-svn: 181381
parent 6156011e
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -3348,13 +3348,15 @@ public:
    void
    RestoreProcessEvents ();

protected:
private:
    //------------------------------------------------------------------
    /// This is the part of the event handling that for a process event.
    /// It decides what to do with the event and returns true if the
    /// event needs to be propagated to the user, and false otherwise.
    /// If the event is not propagated, this call will most likely set
    /// the target to executing again.
    /// There is only one place where this call should be called, HandlePrivateEvent.
    /// Don't call it from anywhere else...
    ///
    /// @param[in] event_ptr
    ///     This is the event we are handling.
@@ -3526,6 +3528,9 @@ protected:
    // new "NextEventAction" is added while one is already present, the
    // old action will be discarded (with HandleBeingUnshipped called 
    // after it is discarded.)
    //
    // If you want to resume the process as a result of a resume action,
    // call RequestResume, don't call Resume directly.
    //------------------------------------------------------------------
    class NextEventAction
    {
@@ -3551,6 +3556,10 @@ protected:
        virtual void HandleBeingUnshipped () {}
        virtual EventActionResult HandleBeingInterrupted () = 0;
        virtual const char *GetExitString() = 0;
        void RequestResume()
        {
            m_process->m_resume_requested = true;
        }
    protected:
        Process *m_process;
    };
@@ -3661,7 +3670,9 @@ protected:
#if defined(__APPLE__)
    ReadWriteLock               m_private_run_lock;
#endif
    Predicate<bool>             m_currently_handling_event;
    Predicate<bool>             m_currently_handling_event; // This predicate is set in HandlePrivateEvent while all its business is being done.
    bool                        m_currently_handling_do_on_removals;
    bool                        m_resume_requested;         // If m_currently_handling_event or m_currently_handling_do_on_removals are true, Resume will only request a resume, using this flag to check.
    bool                        m_finalize_called;
    lldb::StateType             m_last_broadcast_state;   /// This helps with the Public event coalescing in ShouldBroadcastEvent.
    bool m_destroy_in_process;
@@ -3679,7 +3690,7 @@ protected:
    SynchronouslyNotifyStateChanged (lldb::StateType state);

    void
    SetPublicState (lldb::StateType new_state);
    SetPublicState (lldb::StateType new_state, bool restarted);

    void
    SetPrivateState (lldb::StateType state);
+21 −7
Original line number Diff line number Diff line
@@ -79,11 +79,20 @@ public:
        return true;
    }

    void
    OverrideShouldNotify (bool override_value)
    {
        m_override_should_notify = override_value ? eLazyBoolYes : eLazyBoolNo;
    }
    
    // If should stop returns false, check if we should notify of this event
    virtual bool
    ShouldNotify (Event *event_ptr)
    {
        return false;
        if (m_override_should_notify == eLazyBoolCalculate)
            return DoShouldNotify (event_ptr);
        else
            return m_override_should_notify == eLazyBoolYes;
    }

    virtual void
@@ -116,20 +125,19 @@ public:
    void
    OverrideShouldStop (bool override_value)
    {
        m_override_set = true;
        m_override_value = override_value;
        m_override_should_stop = override_value ? eLazyBoolYes : eLazyBoolNo;
    }
    
    bool
    GetOverrideShouldStop()
    {
        return m_override_set;
        return m_override_should_stop != eLazyBoolCalculate;
    }
    
    bool
    GetOverriddenShouldStopValue ()
    {
        return m_override_value;
        return m_override_should_stop == eLazyBoolYes;
    }
    
    static lldb::StopInfoSP
@@ -169,6 +177,12 @@ protected:
    {
    }

    virtual bool
    DoShouldNotify (Event *event_ptr)
    {
        return false;
    }
    
    // Stop the thread by default. Subclasses can override this to allow
    // the thread to continue if desired.  The ShouldStop method should not do anything
    // that might run code.  If you need to run code when deciding whether to stop
@@ -189,8 +203,8 @@ protected:
    uint32_t        m_resume_id; // This is the resume ID when we made this stop ID.
    uint64_t        m_value;    // A generic value that can be used for things pertaining to this stop info
    std::string     m_description; // A textual description describing this stop.
    bool            m_override_set;
    bool            m_override_value;
    LazyBool        m_override_should_notify;
    LazyBool        m_override_should_stop;
    
    // This determines whether the target has run since this stop info.
    // N.B. running to evaluate a user expression does not count. 
+5 −2
Original line number Diff line number Diff line
@@ -927,6 +927,9 @@ public:
    void
    SetStopInfo (const lldb::StopInfoSP &stop_info_sp);

    void
    SetShouldReportStop (Vote vote);

protected:

    friend class ThreadPlan;
@@ -1015,7 +1018,7 @@ protected:
    bool                m_destroy_called;       // This is used internally to make sure derived Thread classes call DestroyThread.
    uint32_t m_thread_stop_reason_stop_id;      // This is the stop id for which the StopInfo is valid.  Can use this so you know that
                                                // the thread's m_actual_stop_info_sp is current and you don't have to fetch it again

    LazyBool            m_override_should_notify;
private:
    //------------------------------------------------------------------
    // For Thread only
+3 −0
Original line number Diff line number Diff line
@@ -136,6 +136,9 @@ public:
    
protected:

    void
    SetShouldReportStop (Vote vote);

    void
    NotifySelectedThreadChanged (lldb::tid_t tid);

+30 −6
Original line number Diff line number Diff line
@@ -92,7 +92,8 @@ namespace lldb_private {
//  When the target process is about to be restarted, the plan's WillResume method is called,
//  giving the plan a chance to prepare for the run.  If WillResume returns false, then the
//  process is not restarted.  Be sure to set an appropriate error value in the Process if
//  you have to do this.
//  you have to do this.  Note, ThreadPlans actually implement DoWillResume, WillResume wraps that call.
//
//  Next the "StopOthers" method of all the threads are polled, and if one thread's Current plan
//  returns "true" then only that thread gets to run.  If more than one returns "true" the threads that want to run solo
//  get run one by one round robin fashion.  Otherwise all are let to run.
@@ -115,6 +116,8 @@ namespace lldb_private {
//  figure out what to do about the plans below it in the stack.  If the stop is recoverable, then the plan that
//  understands it can just do what it needs to set up to restart, and then continue.
//  Otherwise, the plan that understood the stop should call DiscardPlanStack to clean up the stack below it.
//  Note, plans actually implement DoPlanExplainsStop, the result is cached in PlanExplainsStop so the DoPlanExplainsStop
//  itself will only get called once per stop.
//
//  Master plans:
//
@@ -331,9 +334,6 @@ public:
    virtual bool
    ValidatePlan (Stream *error) = 0;

    virtual bool
    PlanExplainsStop (Event *event_ptr) = 0;
    
    bool
    TracerExplainsStop ()
    {
@@ -347,6 +347,9 @@ public:
    lldb::StateType
    RunState ();

    bool
    PlanExplainsStop (Event *event_ptr);
    
    virtual bool
    ShouldStop (Event *event_ptr) = 0;
    
@@ -371,7 +374,9 @@ public:
    virtual bool
    StopOthers ();

    virtual bool
    // This is the wrapper for DoWillResume that does generic ThreadPlan logic, then
    // calls DoWillResume.
    bool
    WillResume (lldb::StateType resume_state, bool current_plan);
    
    virtual bool
@@ -510,6 +515,12 @@ protected:
    // Classes that inherit from ThreadPlan can see and modify these
    //------------------------------------------------------------------

    virtual bool
    DoWillResume (lldb::StateType resume_state, bool current_plan) { return true; };

    virtual bool
    DoPlanExplainsStop (Event *event_ptr) = 0;
    
    // This gets the previous plan to the current plan (for forwarding requests).
    // This is mostly a formal requirement, it allows us to make the Thread's
    // GetPreviousPlan protected, but only friend ThreadPlan to thread.
@@ -535,6 +546,18 @@ protected:
        m_thread.SetStopInfo (stop_reason_sp);
    }
    
    void
    CachePlanExplainsStop (bool does_explain)
    {
        m_cached_plan_explains_stop = does_explain ? eLazyBoolYes : eLazyBoolNo;
    }
    
    LazyBool
    GetCachedPlanExplainsStop () const
    {
        return m_cached_plan_explains_stop;
    }
    
    virtual lldb::StateType
    GetPlanRunState () = 0;

@@ -551,6 +574,7 @@ private:
    ThreadPlanKind m_kind;
    std::string m_name;
    Mutex m_plan_complete_mutex;
    LazyBool m_cached_plan_explains_stop;
    bool m_plan_complete;
    bool m_plan_private;
    bool m_okay_to_discard;
Loading