Handle stepping through ObjC vtable trampoline code.
git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@118270 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Target/ThreadPlanStepInRange.cpp b/source/Target/ThreadPlanStepInRange.cpp
index 2be9380..c19477c 100644
--- a/source/Target/ThreadPlanStepInRange.cpp
+++ b/source/Target/ThreadPlanStepInRange.cpp
@@ -83,23 +83,6 @@
if (InRange())
return false;
- // If we're in an older frame then we should stop.
- if (FrameIsOlder())
- return true;
-
- // See if we are in a place we should step through (i.e. a trampoline of some sort):
- // One tricky bit here is that some stubs don't push a frame, so we have to check
- // both the case of a frame that is younger, or the same as this frame.
- // However, if the frame is the same, and we are still in the symbol we started
- // in, the we don't need to do this. This first check isn't strictly necessary,
- // but it is more efficient.
-
- if (!FrameIsYounger() && InSymbol())
- {
- SetPlanComplete();
- return true;
- }
-
ThreadPlan* new_plan = NULL;
// Stepping through should be done stopping other threads in general, since we're setting a breakpoint and
@@ -111,7 +94,39 @@
else
stop_others = false;
- new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others);
+ if (FrameIsOlder())
+ {
+ // If we're in an older frame then we should stop.
+ //
+ // A caveat to this is if we think the frame is older but we're actually in a trampoline.
+ // I'm going to make the assumption that you wouldn't RETURN to a trampoline. So if we are
+ // in a trampoline we think the frame is older because the trampoline confused the backtracer.
+ new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others);
+ if (new_plan == NULL)
+ return true;
+ else if (log)
+ {
+ log->Printf("Thought I stepped out, but in fact arrived at a trampoline.");
+ }
+
+ }
+ else if (!FrameIsYounger() && InSymbol())
+ {
+ // If we are not in a place we should step through, we're done.
+ // One tricky bit here is that some stubs don't push a frame, so we have to check
+ // both the case of a frame that is younger, or the same as this frame.
+ // However, if the frame is the same, and we are still in the symbol we started
+ // in, the we don't need to do this. This first check isn't strictly necessary,
+ // but it is more efficient.
+
+ SetPlanComplete();
+ return true;
+ }
+
+ // We may have set the plan up above in the FrameIsOlder section:
+
+ if (new_plan == NULL)
+ new_plan = m_thread.QueueThreadPlanForStepThrough (false, stop_others);
if (log)
{