| Anonymous | Login | Signup for a new account | 2013-05-22 20:32 BST | ![]() |
| Main | My View | View Issues | Change Log | Roadmap |
| View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | |||||||
| ID | Project | Category | View Status | Date Submitted | Last Update | |||
| 0000842 | Xdebug | Usage problems | public | 2012-05-25 04:57 | 2012-06-27 22:11 | |||
| Reporter | dinu | |||||||
| Assigned To | derick | |||||||
| Priority | normal | Severity | minor | Reproducibility | always | |||
| Status | resolved | Resolution | not fixable | |||||
| Platform | OS | OS Version | ||||||
| Product Version | 2.2.0 | |||||||
| Target Version | Fixed in Version | |||||||
| Summary | 0000842: 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 Reproduce | 1) Try to get debugger to step on the return statement if($random) return 1; else return 2; 2) Step into callThis(), then step out; no possibility to step callThat() if(callThis()||callThat()){ } | |||||||
| Tags | No tags attached. | |||||||
| Operating System | ||||||||
| PHP Version | 5.3.3 | |||||||
| Attached Files | ||||||||
Notes |
|
|
(0002192) 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. |
|
(0002193) 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. |
|
(0002208) 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 if($cond) doThis(); else doThat(); |
|
(0002226) 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. |
|
(0002227) 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();
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 |
|
(0002228) 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 |
|
(0002299) 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 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. |
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 |
| Copyright © 2000 - 2011 MantisBT Group |