MantisBT

View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0001165XdebugFeature/Change requestpublic2015-06-20 19:302016-12-11 15:43
Reporterunknownbrackets 
Assigned Toderick 
PrioritynormalSeverityminorReproducibilityalways
StatusclosedResolutionfixed 
PlatformOSOS Version
Product Version2.3.3 
Target VersionFixed in Version2.5.1 
Summary0001165: Step Out skips subsequent function calls
DescriptionXdebug performs the "step out" or "finish" operation based on stack level, rather than function unit.

What this means is that when you Step Out from a function that is an argument, or a method that is part of a chain, it behaves incorrectly with respect to standard debugging behavior found in other languages.

-[Unknown]
Steps To Reproduce1. Create a source file with the following content:
<?php

function foo($arg)
{
    echo $arg;
}

function bar()
{
    return 42;
}

foo(bar());
echo 6 * 9;

?>

2. Set a breakpoint on the line containing "foo(bar());" and begin debugging.

3. When the breakpoint trips, execute a step_into, moving you inside bar().

4. Next, execute a step_out. Expect to leave the "bar()" function unit, and enter the "foo()" function unit.

5. Currently, observe that execution is moved to the "echo 6 * 9;" line instead.
Additional InformationI'm thinking of attempting a patch for this. My thinking is that this would require examining op_array, and potentially storing more info to determine a change in active function unit.

Would you accept such a patch? Do you expect it necessary to include an option to retain the old, but unusual, stepping behavior?
TagsNo tags attached.
Operating SystemAny
PHP Version5.6.5-5.6.9
Attached Files

- Relationships
has duplicate 0000842resolvedderick Can't debug conditional statements without a block 

-  Notes
(0003145)
unknownbrackets (reporter)
2015-07-04 02:00
edited on: 2015-07-04 02:05

I suppose the easiest way would be to check op_array->function_name and op_array->scope->name. So something like this:

if (XG(context).do_finish) { /* could still check level to try to skip some? */
   int match = 0;
   zend_string *stmt_func_name = op_array->function_name;
   zend_string *stmt_scope_name = op_array->scope ? op_array->scope->name : NULL;
   zend_string *leave_func_name = XG(context).next_leave_function_name;
   zend_string *leave_scope_name = XG(context).next_leave_scope_name;

   if (!stmt_func_name || !leave_func_name) {
      match = stmt_func_name == leave_func_name;
   } else if (zend_string_equals(stmt_func_name, leave_func_name)) {
      if (!stmt_scope_name || !leave_scope_name) {
         match = stmt_scope_name == leave_scope_name;
      } else if (zend_string_equals(stmt_scope_name, leave_scope_name)) {
         match = 1;
      }
   }

   if (!match) {
      /* break */
   }
}

In a common case, I suppose the pointers would be identical, so it might not perform badly to simply refcount it. I'm not super familiar with the PHP source, though.

Also would need to check if that handles namespaces right.

-[Unknown]

(0003146)
unknownbrackets (reporter)
2015-07-06 02:47

Hmm, closures also - line_start might be necessary.

-[Unknown]
(0003993)
derick (administrator)
2016-12-11 15:43

Fixed in Git for 2.5.1 by comparing the function numbers.

- Issue History
Date Modified Username Field Change
2015-06-20 19:30 unknownbrackets New Issue
2015-07-04 02:00 unknownbrackets Note Added: 0003145
2015-07-04 02:05 unknownbrackets Note Edited: 0003145 View Revisions
2015-07-04 02:05 unknownbrackets Note Edited: 0003145 View Revisions
2015-07-06 02:47 unknownbrackets Note Added: 0003146
2016-12-11 15:23 derick Relationship added has duplicate 0000842
2016-12-11 15:43 derick Note Added: 0003993
2016-12-11 15:43 derick Status new => closed
2016-12-11 15:43 derick Assigned To => derick
2016-12-11 15:43 derick Resolution open => fixed
2016-12-11 15:43 derick Fixed in Version => 2.5.1


Copyright © 2000 - 2017 MantisBT Team
Powered by Mantis Bugtracker