diff options
author | Jim Ingham <jingham@apple.com> | 2014-03-13 02:47:14 +0000 |
---|---|---|
committer | Jim Ingham <jingham@apple.com> | 2014-03-13 02:47:14 +0000 |
commit | 4b4b2478fc4a08d035a7653ae7acaa1853553b34 (patch) | |
tree | b8515657d5f9554f47877b15f8f9c06c05e5b2df /lldb/source/Target/ThreadPlanShouldStopHere.cpp | |
parent | 3e89dfee00f647b9aff301d2fd1076b008666481 (diff) | |
download | bcm5719-llvm-4b4b2478fc4a08d035a7653ae7acaa1853553b34.tar.gz bcm5719-llvm-4b4b2478fc4a08d035a7653ae7acaa1853553b34.zip |
This commit reworks how the thread plan's ShouldStopHere mechanism works, so that it is useful not only
for customizing "step-in" behavior (e.g. step-in doesn't step into code with no debug info), but also
the behavior of step-in/step-out and step-over when they step out of the frame they started in.
I also added as a proof of concept of this reworking a mode for stepping where stepping out of a frame
into a frame with no debug information will continue stepping out till it arrives at a frame that does
have debug information. This is useful when you are debugging callback based code where the callbacks
are separated from the code that initiated them by some library glue you don't care about, among other
things.
llvm-svn: 203747
Diffstat (limited to 'lldb/source/Target/ThreadPlanShouldStopHere.cpp')
-rw-r--r-- | lldb/source/Target/ThreadPlanShouldStopHere.cpp | 108 |
1 files changed, 84 insertions, 24 deletions
diff --git a/lldb/source/Target/ThreadPlanShouldStopHere.cpp b/lldb/source/Target/ThreadPlanShouldStopHere.cpp index 87662345a06..7ef615bcc9f 100644 --- a/lldb/source/Target/ThreadPlanShouldStopHere.cpp +++ b/lldb/source/Target/ThreadPlanShouldStopHere.cpp @@ -23,12 +23,23 @@ using namespace lldb_private; //---------------------------------------------------------------------- // ThreadPlanShouldStopHere constructor //---------------------------------------------------------------------- -ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner, ThreadPlanShouldStopHereCallback callback, void *baton) : - m_callback (callback), - m_baton (baton), +ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner) : + m_callbacks (), + m_baton (NULL), m_owner (owner), m_flags (ThreadPlanShouldStopHere::eNone) { + m_callbacks.should_stop_here_callback = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback; + m_callbacks.step_from_here_callback = ThreadPlanShouldStopHere::DefaultStepFromHereCallback; +} + +ThreadPlanShouldStopHere::ThreadPlanShouldStopHere(ThreadPlan *owner, const ThreadPlanShouldStopHereCallbacks *callbacks, void *baton) : + m_callbacks (), + m_baton (), + m_owner (owner), + m_flags (ThreadPlanShouldStopHere::eNone) +{ + SetShouldStopHereCallbacks(callbacks, baton); } //---------------------------------------------------------------------- @@ -38,37 +49,86 @@ ThreadPlanShouldStopHere::~ThreadPlanShouldStopHere() { } -void -ThreadPlanShouldStopHere::SetShouldStopHereCallback (ThreadPlanShouldStopHereCallback callback, void *baton) -{ - m_callback = callback; - m_baton = baton; -} - -ThreadPlanSP -ThreadPlanShouldStopHere::InvokeShouldStopHereCallback () +bool +ThreadPlanShouldStopHere::InvokeShouldStopHereCallback (FrameComparison operation) { - if (m_callback) + bool should_stop_here = true; + if (m_callbacks.should_stop_here_callback) { - ThreadPlanSP return_plan_sp(m_callback (m_owner, m_flags, m_baton)); + should_stop_here = m_callbacks.should_stop_here_callback (m_owner, m_flags, operation, m_baton); Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); if (log) { lldb::addr_t current_addr = m_owner->GetThread().GetRegisterContext()->GetPC(0); - if (return_plan_sp) - { - StreamString s; - return_plan_sp->GetDescription (&s, lldb::eDescriptionLevelFull); - log->Printf ("ShouldStopHere callback found a step out plan from 0x%" PRIx64 ": %s.", current_addr, s.GetData()); - } - else - { - log->Printf ("ShouldStopHere callback didn't find a step out plan from: 0x%" PRIx64 ".", current_addr); - } + log->Printf ("ShouldStopHere callback returned %u from 0x%" PRIx64 ".", should_stop_here, current_addr); } + } + + return should_stop_here; +} + +bool +ThreadPlanShouldStopHere::DefaultShouldStopHereCallback (ThreadPlan *current_plan, + Flags &flags, + FrameComparison operation, + void *baton) +{ + bool should_stop_here = true; + StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get(); + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); + + if ((operation == eFrameCompareOlder && flags.Test(eStepOutAvoidNoDebug)) + || (operation == eFrameCompareYounger && flags.Test(eStepInAvoidNoDebug))) + { + if (!frame->HasDebugInformation()) + { + if (log) + log->Printf ("Stepping out of frame with no debug info"); + + should_stop_here = false; + } + } + + return should_stop_here; +} + +ThreadPlanSP +ThreadPlanShouldStopHere::DefaultStepFromHereCallback (ThreadPlan *current_plan, + Flags &flags, + FrameComparison operation, + void *baton) +{ + const bool stop_others = false; + const size_t frame_index = 0; + ThreadPlanSP return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepOutNoShouldStop (false, + NULL, + true, + stop_others, + eVoteNo, + eVoteNoOpinion, + frame_index); return return_plan_sp; +} + +ThreadPlanSP +ThreadPlanShouldStopHere::QueueStepOutFromHerePlan(lldb_private::Flags &flags, lldb::FrameComparison operation) +{ + ThreadPlanSP return_plan_sp; + if (m_callbacks.step_from_here_callback) + { + return_plan_sp = m_callbacks.step_from_here_callback (m_owner, flags, operation, m_baton); } + return return_plan_sp; + +} + +lldb::ThreadPlanSP +ThreadPlanShouldStopHere::CheckShouldStopHereAndQueueStepOut (lldb::FrameComparison operation) +{ + if (!InvokeShouldStopHereCallback(operation)) + return QueueStepOutFromHerePlan(m_flags, operation); else return ThreadPlanSP(); } + |