diff --git a/hphp/runtime/debugger/cmd/cmd_out.cpp b/hphp/runtime/debugger/cmd/cmd_out.cpp index 997a96d6b..17e94bd37 100644 --- a/hphp/runtime/debugger/cmd/cmd_out.cpp +++ b/hphp/runtime/debugger/cmd/cmd_out.cpp @@ -57,21 +57,19 @@ void CmdOut::onBeginInterrupt(DebuggerProxy &proxy, CmdInterrupt &interrupt) { int currentVMDepth = g_vmContext->m_nesting; int currentStackDepth = proxy.getStackDepth(); - if (currentVMDepth < m_vmDepth) { - // Cut corner here, just break when cross VM boundary no matter how - // many levels we want to go out of - TRACE(2, "CmdOut: shallower VM depth, done.\n"); - cleanupStepOuts(); - m_complete = true; - } else if ((currentVMDepth == m_vmDepth) && - (currentStackDepth < m_stackDepth)) { - TRACE(2, "CmdOut: same VM depth, shallower stack depth, done.\n"); - cleanupStepOuts(); - m_complete = (decCount() == 0); - if (!m_complete) { - TRACE(2, "CmdOut: not complete, step out again.\n"); - setupStepOuts(); - } + + // Deeper or same depth? Keep running. + if ((currentVMDepth > m_vmDepth) || + ((currentVMDepth == m_vmDepth) && (currentStackDepth >= m_stackDepth))) { + return; + } + + TRACE(2, "CmdOut: shallower stack depth, done.\n"); + cleanupStepOuts(); + m_complete = (decCount() == 0); + if (!m_complete) { + TRACE(2, "CmdOut: not complete, step out again.\n"); + onSetup(proxy, interrupt); } m_needsVMInterrupt = false; } diff --git a/hphp/test/quick/debugger/flow_multistep.php b/hphp/test/quick/debugger/flow_multistep.php new file mode 100644 index 000000000..4db1c4f67 --- /dev/null +++ b/hphp/test/quick/debugger/flow_multistep.php @@ -0,0 +1,63 @@ + break flow_multistep.php:58 +Breakpoint 1 set on line 58 of flow_multistep.php +hphpd> run +C1 oh hai +C2 oh hai +C2 oh hai +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +object(C1)#1 (1) { + ["x":"C1":private]=> + int(0) +} +Breakpoint 1 reached at main() on line 58 of %s/flow_multistep.php + 57 var_dump($d); + 58 var_dump(a(42)); + 59 } + +hphpd> step 8 +Break at main() on line 58 of %s/flow_multistep.php + 57 var_dump($d); + 58 var_dump(a(42)); + 59 } + +hphpd> continue +int(46) +C1 destructor! +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +Program %s/flow_multistep.php exited normally. +hphpd> run +C1 oh hai +C2 oh hai +C2 oh hai +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +object(C1)#3 (1) { + ["x":"C1":private]=> + int(0) +} +Breakpoint 1 reached at main() on line 58 of %s/flow_multistep.php + 57 var_dump($d); + 58 var_dump(a(42)); + 59 } + +hphpd> step 4 +Break at d() on line 17 of %s/flow_multistep.php + 16 function d($a) { + 17 return $a + 1; + 18 } + +hphpd> step 4 +Break at main() on line 58 of %s/flow_multistep.php + 57 var_dump($d); + 58 var_dump(a(42)); + 59 } + +hphpd> continue +int(46) +C1 destructor! +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +Program %s/flow_multistep.php exited normally. +hphpd> run +C1 oh hai +C2 oh hai +C2 oh hai +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +object(C1)#5 (1) { + ["x":"C1":private]=> + int(0) +} +Breakpoint 1 reached at main() on line 58 of %s/flow_multistep.php + 57 var_dump($d); + 58 var_dump(a(42)); + 59 } + +hphpd> step 4 +Break at d() on line 17 of %s/flow_multistep.php + 16 function d($a) { + 17 return $a + 1; + 18 } + +hphpd> next 4 +Break at main() on line 58 of %s/flow_multistep.php + 57 var_dump($d); + 58 var_dump(a(42)); + 59 } + +hphpd> continue +int(46) +C1 destructor! +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +Program %s/flow_multistep.php exited normally. +hphpd> run +C1 oh hai +C2 oh hai +C2 oh hai +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +object(C1)#7 (1) { + ["x":"C1":private]=> + int(0) +} +Breakpoint 1 reached at main() on line 58 of %s/flow_multistep.php + 57 var_dump($d); + 58 var_dump(a(42)); + 59 } + +hphpd> step 4 +Break at d() on line 17 of %s/flow_multistep.php + 16 function d($a) { + 17 return $a + 1; + 18 } + +hphpd> out 4 +Break at main() on line 58 of %s/flow_multistep.php + 57 var_dump($d); + 58 var_dump(a(42)); + 59 } + +hphpd> continue +int(46) +C1 destructor! +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +Program %s/flow_multistep.php exited normally. +hphpd> break clear all +All breakpoints are cleared. +hphpd> break flow_multistep.php:54 +Breakpoint 1 set on line 54 of flow_multistep.php +hphpd> run +C1 oh hai +C2 oh hai +Breakpoint 1 reached at main() on line 54 of %s/flow_multistep.php + 53 $c2 = new C2(5); + 54 $c2 = new C2(6); + 55 $d = $c1; + +hphpd> break clear all +All breakpoints are cleared. +hphpd> step 10 +C2 oh hai +C2 destructor +C1 oh hai +Break at C1::__destruct() on line 30 of %s/flow_multistep.php + 29 public function __destruct() { + 30 echo "C1 destructor!\n"; + 31 } + +hphpd> out 2 +C1 destructor! +C2 destructor done +Break at main() on line 54 of %s/flow_multistep.php + 53 $c2 = new C2(5); + 54 $c2 = new C2(6); + 55 $d = $c1; + +hphpd> out +object(C1)#9 (1) { + ["x":"C1":private]=> + int(0) +} +int(46) +C1 destructor! +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +Break on line 61 of %s/flow_multistep.php + 60 + 61 main(); + 62 + +hphpd> continue +Program %s/flow_multistep.php exited normally. +hphpd> break flow_multistep.php:54 +Breakpoint 1 set on line 54 of flow_multistep.php +hphpd> run +C1 oh hai +C2 oh hai +Breakpoint 1 reached at main() on line 54 of %s/flow_multistep.php + 53 $c2 = new C2(5); + 54 $c2 = new C2(6); + 55 $d = $c1; + +hphpd> break clear all +All breakpoints are cleared. +hphpd> step 10 +C2 oh hai +C2 destructor +C1 oh hai +Break at C1::__destruct() on line 30 of %s/flow_multistep.php + 29 public function __destruct() { + 30 echo "C1 destructor!\n"; + 31 } + +hphpd> next 3 +C1 destructor! +C2 destructor done +Break at main() on line 54 of %s/flow_multistep.php + 53 $c2 = new C2(5); + 54 $c2 = new C2(6); + 55 $d = $c1; + +hphpd> next +Break at main() on line 55 of %s/flow_multistep.php + 54 $c2 = new C2(6); + 55 $d = $c1; + 56 $c1 = null; + +hphpd> continue +object(C1)#11 (1) { + ["x":"C1":private]=> + int(0) +} +int(46) +C1 destructor! +C2 destructor +C1 oh hai +C1 destructor! +C2 destructor done +Program %s/flow_multistep.php exited normally. +hphpd> quit diff --git a/hphp/test/quick/debugger/flow_multistep.php.in b/hphp/test/quick/debugger/flow_multistep.php.in new file mode 100644 index 000000000..3a5c0a728 --- /dev/null +++ b/hphp/test/quick/debugger/flow_multistep.php.in @@ -0,0 +1,34 @@ +break flow_multistep.php:58 +run +step 8 +continue +run +step 4 +step 4 +continue +run +step 4 +next 4 +continue +run +step 4 +out 4 +continue +break clear all +break flow_multistep.php:54 +run +break clear all +step 10 +out 2 +out +continue +break flow_multistep.php:54 +run +break clear all +step 10 +next 3 +next +continue +quit + + diff --git a/hphp/test/quick/debugger/flow_multistep.php.opts b/hphp/test/quick/debugger/flow_multistep.php.opts new file mode 100644 index 000000000..cf014a32f --- /dev/null +++ b/hphp/test/quick/debugger/flow_multistep.php.opts @@ -0,0 +1 @@ + -m debug \ No newline at end of file