View Issue Details Jump to Notes ] Issue History ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0000842XdebugUsage problems (Wrong Results)public2012-05-25 04:572016-12-11 15:23
Assigned Toderick 
PlatformOSOS Version
Product Version2.2.0 
Target VersionFixed in Version2.5.1 
Summary0000842: Can't debug conditional statements without a block
Description- If a conditional statement does not have {} for its predicates, I can't debug it (using Zend Studio)
- If more function calls are invoked in the condition, stepping out of the first does not resume debugging to the next (i.e. there is no way to debug the 2nd function in a condition).

I myself preach the values of good coding practices. However, I find myself stuck with third-party code that I don't want to restyle, mainly because it comes through a CVS that is regularly updated so I'd rather keep the original shape of the code.
Steps To Reproduce1) Try to get debugger to step on the return statement

  return 1;
  return 2;

2) Step into callThis(), then step out; no possibility to step callThat()

TagsNo tags attached.
Operating System
PHP Version5.3.3
Attached Files

- Relationships
duplicate of 0001165closedderick Step Out skips subsequent function calls 
has duplicate 0000895resolvedderick xdebug never stops on single-line statements 
has duplicate 0001069resolvedderick Wrong coverage generated for single line if statements 

-  Notes
rulatir (reporter)
2012-05-27 21:59

2) Just to eliminate one possibility: if callThis() returns true then callThat() is not called because the result of the logical OR expression is already known. That's an optimization done by PHP.
dinu (reporter)
2012-05-27 23:57

I know, it's pretty standard in any language :) I'm talking about that if the 2 calls are followed.
dinu (reporter)
2012-05-28 13:00

More details: cannot set a breakpoint on a conditional predicate without a block: try to set a breakpoint on doThis() or doThat() line

derick (administrator)
2012-06-01 23:40
edited on: 2012-06-01 23:41

For the first case, breakpoints are tricky. Sadly PHP itself doesn't generate the correct line numbers internally. See for example the code:

 22 function test2($random)
 23 {
 24     if ($random) 
 25         test2a();
 26     else 
 27         test2b();

Which in PHP turns into:

line     # *  op                           fetch          ext  return  operands
  22     0  >   EXT_NOP
         1      RECV                                             !0
  25     2      EXT_STMT
         3    > JMPZ                                                     !0, ->8
         4  >   EXT_FCALL_BEGIN
         5      DO_FCALL                                      0          'test2a'
         6      EXT_FCALL_END
         7    > JMP                                                      ->11
  27     8  >   EXT_FCALL_BEGIN
         9      DO_FCALL                                      0          'test2b'
        10      EXT_FCALL_END
  28    11  >   EXT_STMT
        12    > RETURN                                                   null

as you can see, there is no line 24 or 26. One of the PHP folks is looking at fixing this, but this is currently not something I can address in Xdebug. Even more annoying, the case for "false" also hits line 25 due to PHP weirdness.

I will now have a look at the second case.

dinu (reporter)
2012-06-02 05:08
edited on: 2012-06-02 10:42

By your example, I should be able to set a breakpoint on 25 or 27. Which I am not; I try to ellaborate a litle on a test case:

1 <?php
2	function ret1(){
3		return 1;
4	}
5	function ret2(){
6		return 2;
7	}
8	function dummy1(){
9		echo 'dummy1';
10	}
11	function dummy2(){
12		echo 'dummy2';
13	}
14	if($x)
15		dummy1();
16	else
17		dummy2();
18	if(ret1()&&ret2())
19		dummy1();
20	else
21		dummy2();

- set breakpoints on 15,17,19,21
- expected behavior: stop on 17,19
- actual behavior: breakpoints don't work, BUT debugger inadvertently stops on line 15, BUT on "step into" command goes into dummy2 at 6

- set breakpoint on 14
- expected behavior: stop on 14
- actual behavior: doesn't work as per your explanations

- Step over all the way to 18
- Step into 18; correctly goes into ret1 on 3
- Step out of ret1
- Expected behavior: execution should step into ret2 on 6 (most debuggers do it this way), or _at_least_ on 19 so I can debug dummy1
- Actual behavior: all if is skipped; seems to step out not of the function call but of the statement
- Consequence: the only way to step into a second conditional function or the predicate function is that I have the patience to step all the way through the first conditional function or add incognito breakpoints on function entries

dinu (reporter)
2012-06-02 05:25

More discussion over TS3 where I think a definite improvement can be made: most debuggers I'm familiar with interpret debugger commands on conditional statements the following way:

- Step over if statement
- Usual: breaks on first instruction of the branch taken
- XDEBUG: breaks on first instruction after if statement

- Step into if statement
- Usual&XDEBUG: step into first function in condition

- Step out of conditional function
- Usual: break into the next conditional function then at the first instruction of branch taken
- XDEBUG: break out of if statement
derick (administrator)
2012-06-27 22:11

Marking as "not fixable":

All cases really have the same cause.
In the first bit of TS1 (stop on 17):

It stops on line 15 because of this is where PHP places the if statement:

  15 8 EXT_STMT
         9 > JMPZ !0, ->1

This is something PHP *should* have put on line 14, but didn't. The step-into
goes correctly into dummy2 in line 12 (and not 6 like you wrote). This is
because that's what is the next executable line after the if-JMPZ has been

The second case in TS1 (not stopping on line 19) is because PHP
doesn't generate an EXT_STMT, which is required for breakpoint insertions.

TS2 is indeed because PHP simply generates no code on line 14:

  11 6 EXT_STMT
         7 NOP
  15 8 EXT_STMT

TS3 is because PHP doesn't generate an EXT_STMT before the dummy1 call,
as it would do if you would have used braces. Hence it doesn't stop and
goes directly to the next breakable line in a scope higher than where
you were (the ret1 function online 3), wich is the EXT_STMT in line 23.

You fix all of this by just using braces.
derick (administrator)
2016-12-11 15:23

This turned out to be a duplicate of 1165, for which I now have cooked up a fix, which will make it into 2.5.1.

- Issue History
Date Modified Username Field Change
2012-05-25 04:57 dinu New Issue
2012-05-27 21:59 rulatir Note Added: 0002192
2012-05-27 23:57 dinu Note Added: 0002193
2012-05-28 13:00 dinu Note Added: 0002208
2012-06-01 23:40 derick Note Added: 0002226
2012-06-01 23:40 derick Note Edited: 0002226 View Revisions
2012-06-01 23:41 derick Note Edited: 0002226 View Revisions
2012-06-02 05:08 dinu Note Added: 0002227
2012-06-02 05:25 dinu Note Added: 0002228
2012-06-02 10:42 derick Note Edited: 0002227 View Revisions
2012-06-27 22:11 derick Note Added: 0002299
2012-06-27 22:11 derick Status new => resolved
2012-06-27 22:11 derick Resolution open => not fixable
2012-06-27 22:11 derick Assigned To => derick
2012-10-18 22:53 derick Relationship added has duplicate 0000895
2014-08-14 12:01 derick Relationship added has duplicate 0001069
2016-07-31 13:36 derick Category Usage problems => Usage problems (Crashes)
2016-07-31 13:38 derick Category Usage problems (Crashes) => Usage problems (Wrong Results)
2016-12-11 15:22 derick Status resolved => assigned
2016-12-11 15:23 derick Note Added: 0003992
2016-12-11 15:23 derick Relationship added duplicate of 0001165
2016-12-11 15:23 derick Status assigned => resolved
2016-12-11 15:23 derick Fixed in Version => 2.5.1
2016-12-11 15:23 derick Resolution not fixable => duplicate

Copyright © 2000 - 2017 MantisBT Team
Powered by Mantis Bugtracker