1 //===-- ThreadPlanShouldStopHere.cpp ----------------------------*- 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 #include "lldb/Target/RegisterContext.h" 11 #include "lldb/Target/Thread.h" 12 #include "lldb/Target/ThreadPlanShouldStopHere.h" 13 #include "lldb/Core/Log.h" 14 15 using namespace lldb; 16 using namespace lldb_private; 17 18 // C Includes 19 // C++ Includes 20 // Other libraries and framework includes 21 // Project includes 22 23 //---------------------------------------------------------------------- 24 // ThreadPlanShouldStopHere constructor 25 //---------------------------------------------------------------------- 26 ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner) : 27 m_callbacks (), 28 m_baton (NULL), 29 m_owner (owner), 30 m_flags (ThreadPlanShouldStopHere::eNone) 31 { 32 m_callbacks.should_stop_here_callback = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback; 33 m_callbacks.step_from_here_callback = ThreadPlanShouldStopHere::DefaultStepFromHereCallback; 34 } 35 36 ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner, const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton) : 37 m_callbacks (), 38 m_baton (), 39 m_owner (owner), 40 m_flags (ThreadPlanShouldStopHere::eNone) 41 { 42 SetShouldStopHereCallbacks(callbacks, baton); 43 } 44 45 //---------------------------------------------------------------------- 46 // Destructor 47 //---------------------------------------------------------------------- 48 ThreadPlanShouldStopHere::~ThreadPlanShouldStopHere() 49 { 50 } 51 52 bool 53 ThreadPlanShouldStopHere::InvokeShouldStopHereCallback (FrameComparison operation) 54 { 55 bool should_stop_here = true; 56 if (m_callbacks.should_stop_here_callback) 57 { 58 should_stop_here = m_callbacks.should_stop_here_callback (m_owner, m_flags, operation, m_baton); 59 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 60 if (log) 61 { 62 lldb::addr_t current_addr = m_owner->GetThread().GetRegisterContext()->GetPC(0); 63 64 log->Printf ("ShouldStopHere callback returned %u from 0x%" PRIx64 ".", should_stop_here, current_addr); 65 } 66 } 67 68 return should_stop_here; 69 } 70 71 bool 72 ThreadPlanShouldStopHere::DefaultShouldStopHereCallback (ThreadPlan *current_plan, 73 Flags &flags, 74 FrameComparison operation, 75 void *baton) 76 { 77 bool should_stop_here = true; 78 StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); 79 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 80 81 if ((operation == eFrameCompareOlder && flags.Test(eStepOutAvoidNoDebug)) 82 || (operation == eFrameCompareYounger && flags.Test(eStepInAvoidNoDebug))) 83 { 84 if (!frame->HasDebugInformation()) 85 { 86 if (log) 87 log->Printf ("Stepping out of frame with no debug info"); 88 89 should_stop_here = false; 90 } 91 } 92 93 return should_stop_here; 94 } 95 96 ThreadPlanSP 97 ThreadPlanShouldStopHere::DefaultStepFromHereCallback (ThreadPlan *current_plan, 98 Flags &flags, 99 FrameComparison operation, 100 void *baton) 101 { 102 const bool stop_others = false; 103 const size_t frame_index = 0; 104 ThreadPlanSP return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepOutNoShouldStop (false, 105 NULL, 106 true, 107 stop_others, 108 eVoteNo, 109 eVoteNoOpinion, 110 frame_index); 111 return return_plan_sp; 112 } 113 114 ThreadPlanSP 115 ThreadPlanShouldStopHere::QueueStepOutFromHerePlan(lldb_private::Flags &flags, lldb::FrameComparison operation) 116 { 117 ThreadPlanSP return_plan_sp; 118 if (m_callbacks.step_from_here_callback) 119 { 120 return_plan_sp = m_callbacks.step_from_here_callback (m_owner, flags, operation, m_baton); 121 } 122 return return_plan_sp; 123 124 } 125 126 lldb::ThreadPlanSP 127 ThreadPlanShouldStopHere::CheckShouldStopHereAndQueueStepOut (lldb::FrameComparison operation) 128 { 129 if (!InvokeShouldStopHereCallback(operation)) 130 return QueueStepOutFromHerePlan(m_flags, operation); 131 else 132 return ThreadPlanSP(); 133 } 134 135