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 #include "lldb/Target/ThreadPlan.h" 14 15 namespace lldb_private { 16 17 // This is an interface that ThreadPlans can adopt to allow flexible 18 // modifications of the behavior when a thread plan comes to a place where it 19 // would ordinarily stop. If such modification makes sense for your plan, 20 // inherit from this class, and when you would be about to stop (in your 21 // ShouldStop method), call InvokeShouldStopHereCallback, passing in the frame 22 // comparison between where the step operation started and where you arrived. 23 // If it returns true, then QueueStepOutFromHere will queue the plan to execute 24 // instead of stopping. 25 // 26 // The classic example of the use of this is ThreadPlanStepInRange not stopping 27 // in frames that have no debug information. 28 // 29 // This class also defines a set of flags to control general aspects of this 30 // "ShouldStop" behavior. 31 // A class implementing this protocol needs to define a default set of flags, 32 // and can provide access to 33 // changing that default flag set if it wishes. 34 35 class ThreadPlanShouldStopHere { 36 public: 37 struct ThreadPlanShouldStopHereCallbacks { ThreadPlanShouldStopHereCallbacksThreadPlanShouldStopHereCallbacks38 ThreadPlanShouldStopHereCallbacks() { 39 should_stop_here_callback = nullptr; 40 step_from_here_callback = nullptr; 41 } 42 ThreadPlanShouldStopHereCallbacksThreadPlanShouldStopHereCallbacks43 ThreadPlanShouldStopHereCallbacks( 44 ThreadPlanShouldStopHereCallback should_stop, 45 ThreadPlanStepFromHereCallback step_from_here) { 46 should_stop_here_callback = should_stop; 47 step_from_here_callback = step_from_here; 48 } 49 ClearThreadPlanShouldStopHereCallbacks50 void Clear() { 51 should_stop_here_callback = nullptr; 52 step_from_here_callback = nullptr; 53 } 54 55 ThreadPlanShouldStopHereCallback should_stop_here_callback; 56 ThreadPlanStepFromHereCallback step_from_here_callback; 57 }; 58 59 enum { 60 eNone = 0, 61 eAvoidInlines = (1 << 0), 62 eStepInAvoidNoDebug = (1 << 1), 63 eStepOutAvoidNoDebug = (1 << 2) 64 }; 65 66 //------------------------------------------------------------------ 67 // Constructors and Destructors 68 //------------------------------------------------------------------ 69 ThreadPlanShouldStopHere(ThreadPlan *owner); 70 71 ThreadPlanShouldStopHere(ThreadPlan *owner, 72 const ThreadPlanShouldStopHereCallbacks *callbacks, 73 void *baton = nullptr); 74 virtual ~ThreadPlanShouldStopHere(); 75 76 // Set the ShouldStopHere callbacks. Pass in null to clear them and have no 77 // special behavior (though you can also call ClearShouldStopHereCallbacks 78 // for that purpose. If you pass in a valid pointer, it will adopt the non- 79 // null fields, and any null fields will be set to the default values. 80 81 void SetShouldStopHereCallbacks(const ThreadPlanShouldStopHereCallbacks * callbacks,void * baton)82 SetShouldStopHereCallbacks(const ThreadPlanShouldStopHereCallbacks *callbacks, 83 void *baton) { 84 if (callbacks) { 85 m_callbacks = *callbacks; 86 if (!m_callbacks.should_stop_here_callback) 87 m_callbacks.should_stop_here_callback = 88 ThreadPlanShouldStopHere::DefaultShouldStopHereCallback; 89 if (!m_callbacks.step_from_here_callback) 90 m_callbacks.step_from_here_callback = 91 ThreadPlanShouldStopHere::DefaultStepFromHereCallback; 92 } else { 93 ClearShouldStopHereCallbacks(); 94 } 95 m_baton = baton; 96 } 97 ClearShouldStopHereCallbacks()98 void ClearShouldStopHereCallbacks() { m_callbacks.Clear(); } 99 100 bool InvokeShouldStopHereCallback(lldb::FrameComparison operation, 101 Status &status); 102 103 lldb::ThreadPlanSP 104 CheckShouldStopHereAndQueueStepOut(lldb::FrameComparison operation, 105 Status &status); 106 GetFlags()107 lldb_private::Flags &GetFlags() { return m_flags; } 108 GetFlags()109 const lldb_private::Flags &GetFlags() const { return m_flags; } 110 111 protected: 112 static bool DefaultShouldStopHereCallback(ThreadPlan *current_plan, 113 Flags &flags, 114 lldb::FrameComparison operation, 115 Status &status, void *baton); 116 117 static lldb::ThreadPlanSP 118 DefaultStepFromHereCallback(ThreadPlan *current_plan, Flags &flags, 119 lldb::FrameComparison operation, Status &status, 120 void *baton); 121 122 virtual lldb::ThreadPlanSP 123 QueueStepOutFromHerePlan(Flags &flags, lldb::FrameComparison operation, 124 Status &status); 125 126 // Implement this, and call it in the plan's constructor to set the default 127 // flags. 128 virtual void SetFlagsToDefault() = 0; 129 130 ThreadPlanShouldStopHereCallbacks m_callbacks; 131 void *m_baton; 132 ThreadPlan *m_owner; 133 lldb_private::Flags m_flags; 134 135 private: 136 DISALLOW_COPY_AND_ASSIGN(ThreadPlanShouldStopHere); 137 }; 138 139 } // namespace lldb_private 140 141 #endif // liblldb_ThreadPlanShouldStopHere_h_ 142