1 //===-- ThreadPlanShouldStopHere.h ------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #ifndef liblldb_ThreadPlanShouldStopHere_h_ 11 #define liblldb_ThreadPlanShouldStopHere_h_ 12 13 // C Includes 14 // C++ Includes 15 // Other libraries and framework includes 16 // Project includes 17 #include "lldb/Target/ThreadPlan.h" 18 19 namespace lldb_private { 20 21 // This is an interface that ThreadPlans can adopt to allow flexible modifications of the behavior 22 // when a thread plan comes to a place where it would ordinarily stop. If such modification makes 23 // sense for your plan, inherit from this class, and when you would be about to stop (in your ShouldStop 24 // method), call InvokeShouldStopHereCallback, passing in the frame comparison between where the step operation 25 // started and where you arrived. If it returns true, then QueueStepOutFromHere will queue the plan 26 // to execute instead of stopping. 27 // 28 // The classic example of the use of this is ThreadPlanStepInRange not stopping in frames that have 29 // no debug information. 30 // 31 // This class also defines a set of flags to control general aspects of this "ShouldStop" behavior. 32 // A class implementing this protocol needs to define a default set of flags, and can provide access to 33 // changing that default flag set if it wishes. 34 35 class ThreadPlanShouldStopHere 36 { 37 public: 38 struct ThreadPlanShouldStopHereCallbacks 39 { ThreadPlanShouldStopHereCallbacksThreadPlanShouldStopHereCallbacks40 ThreadPlanShouldStopHereCallbacks() 41 { 42 should_stop_here_callback = nullptr; 43 step_from_here_callback = nullptr; 44 } 45 ThreadPlanShouldStopHereCallbacksThreadPlanShouldStopHereCallbacks46 ThreadPlanShouldStopHereCallbacks(ThreadPlanShouldStopHereCallback should_stop, 47 ThreadPlanStepFromHereCallback step_from_here) 48 { 49 should_stop_here_callback = should_stop; 50 step_from_here_callback = step_from_here; 51 } 52 53 void ClearThreadPlanShouldStopHereCallbacks54 Clear() 55 { 56 should_stop_here_callback = nullptr; 57 step_from_here_callback = nullptr; 58 } 59 60 ThreadPlanShouldStopHereCallback should_stop_here_callback; 61 ThreadPlanStepFromHereCallback step_from_here_callback; 62 }; 63 64 enum 65 { 66 eNone = 0, 67 eAvoidInlines = (1 << 0), 68 eStepInAvoidNoDebug = (1 << 1), 69 eStepOutAvoidNoDebug = (1 << 2) 70 }; 71 72 //------------------------------------------------------------------ 73 // Constructors and Destructors 74 //------------------------------------------------------------------ 75 ThreadPlanShouldStopHere (ThreadPlan *owner); 76 77 ThreadPlanShouldStopHere (ThreadPlan *owner, 78 const ThreadPlanShouldStopHereCallbacks *callbacks, 79 void *baton = NULL); 80 virtual 81 ~ThreadPlanShouldStopHere(); 82 83 // Set the ShouldStopHere callbacks. Pass in null to clear them and have no special behavior (though you 84 // can also call ClearShouldStopHereCallbacks for that purpose. If you pass in a valid pointer, it will 85 // adopt the non-null fields, and any null fields will be set to the default values. 86 87 void SetShouldStopHereCallbacks(const ThreadPlanShouldStopHereCallbacks * callbacks,void * baton)88 SetShouldStopHereCallbacks (const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton) 89 { 90 if (callbacks) 91 { 92 m_callbacks = *callbacks; 93 if (!m_callbacks.should_stop_here_callback) 94 m_callbacks.should_stop_here_callback = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback; 95 if (!m_callbacks.step_from_here_callback) 96 m_callbacks.step_from_here_callback = ThreadPlanShouldStopHere::DefaultStepFromHereCallback; 97 } 98 else 99 { 100 ClearShouldStopHereCallbacks (); 101 } 102 m_baton = baton; 103 } 104 105 void ClearShouldStopHereCallbacks()106 ClearShouldStopHereCallbacks() 107 { 108 m_callbacks.Clear(); 109 } 110 111 bool 112 InvokeShouldStopHereCallback (lldb::FrameComparison operation); 113 114 lldb::ThreadPlanSP 115 CheckShouldStopHereAndQueueStepOut (lldb::FrameComparison operation); 116 117 lldb_private::Flags & GetFlags()118 GetFlags () 119 { 120 return m_flags; 121 } 122 123 const lldb_private::Flags & GetFlags()124 GetFlags () const 125 { 126 return m_flags; 127 } 128 129 protected: 130 static bool 131 DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); 132 133 static lldb::ThreadPlanSP 134 DefaultStepFromHereCallback (ThreadPlan *current_plan, Flags &flags, lldb::FrameComparison operation, void *baton); 135 136 virtual lldb::ThreadPlanSP 137 QueueStepOutFromHerePlan (Flags &flags, lldb::FrameComparison operation); 138 139 // Implement this, and call it in the plan's constructor to set the default flags. 140 virtual void SetFlagsToDefault () = 0; 141 142 //------------------------------------------------------------------ 143 // Classes that inherit from ThreadPlanShouldStopHere can see and modify these 144 //------------------------------------------------------------------ 145 ThreadPlanShouldStopHereCallbacks m_callbacks; 146 void * m_baton; 147 ThreadPlan *m_owner; 148 lldb_private::Flags m_flags; 149 150 private: 151 //------------------------------------------------------------------ 152 // For ThreadPlanShouldStopHere only 153 //------------------------------------------------------------------ 154 155 DISALLOW_COPY_AND_ASSIGN (ThreadPlanShouldStopHere); 156 157 }; 158 159 } // namespace lldb_private 160 161 #endif // liblldb_ThreadPlanShouldStopHere_h_ 162