rulatir 2012-05-27 20:59 reporter ~0002192 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 2012-05-27 22:57 reporter ~0002193 I know, it's pretty standard in any language :) I'm talking about that if the 2 calls are followed.

dinu 2012-05-28 12:00 reporter ~0002208 More details: cannot set a breakpoint on a conditional predicate without a block: try to set a breakpoint on doThis() or doThat() line



if($cond)

doThis();

else

doThat();

derick 2012-06-01 22:40 administrator ~0002226 Last edited: 2012-06-01 22:41 View 3 revisions 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 2012-06-02 04:08 reporter ~0002227 Last edited: 2012-06-02 09:42 View 2 revisions 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();



TS1:

- 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



TS2:

- set breakpoint on 14

- expected behavior: stop on 14

- actual behavior: doesn't work as per your explanations



TS3:

- 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 2012-06-02 04:25 reporter ~0002228 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 2012-06-27 21:11 administrator ~0002299 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

done.



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.