View Issue Details

IDProjectCategoryView StatusLast Update
0001089XdebugUncategorizedpublic2015-01-07 10:26
Reporteredrjoe Assigned Toderick  
PriorityhighSeveritymajorReproducibilityalways
Status resolvedResolutionno change required 
PlatformLinuxOSRHELOS Version6.4
Product Version2.2.5 
Summary0001089: Call to php_sapi_name() breaks exception handling
Description

Combination of XDebug 2.2.5-6 + OpCache-7.0.4 + PHP 5.6.3 (turn either Xdebug OR ZO+ off, and problem goes away...), and a call to php_sapi_name() causes Exceptions that are caught and rethrown to immediately propagate to exception handler and ignore further catch statements.

Steps To Reproduce

<?php

if(php_sapi_name()) {
try { // 1
try { // 2
throw new Exception('Raaaa');
} catch (Exception $e) { // 2
echo 'hello';
throw $e;
}
} catch (Exception $e1) { // 1
// squash
}
}

Additional Information

Disabling either XDebug OR ZO+ fixes the issue. The call to php_sapi_name() is required. php_sapi_name() call has to be in logic - just calling it on it's own doesn't work.

Workaround: use PHP_SAPI constant instead.

TagsNo tags attached.
Attached Files
opcode-on.txt (3,458 bytes)   
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 20
Branch analysis from position: 5
Jump found. Position 1 = -2
Branch analysis from position: 20
Jump found. Position 1 = -2
Found catch point at position: 13
Branch analysis from position: 13
Jump found. Position 1 = 14, Position 2 = -2
Branch analysis from position: 14
Jump found. Position 1 = -2
Found catch point at position: 19
Branch analysis from position: 19
Jump found. Position 1 = 20, Position 2 = -2
Branch analysis from position: 20
filename:       /home/derick/dev/php/derickr-xdebug/tests/bug01089.php
function name:  (null)
number of ops:  22
compiled vars:  !0 = $e, !1 = $e1
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   EXT_STMT                                                 
         1        EXT_FCALL_BEGIN                                          
         2        DO_FCALL                                      0  $0      'php_sapi_name'
         3        EXT_FCALL_END                                            
         4      > JMPZ                                                     $0, ->20
   5     5    >   EXT_STMT                                                 
         6        FETCH_CLASS                                   0  :1      'Exception'
         7        EXT_FCALL_BEGIN                                          
         8        NEW                                              $0      :1
         9        SEND_VAL                                                 'Raaaa'
        10        DO_FCALL_BY_NAME                              1          
        11        EXT_FCALL_END                                            
        12      > THROW                                         0          $0
   6    13  E > > CATCH                                        18          'Exception', !0
   7    14    >   EXT_STMT                                                 
        15        ECHO                                                     'hello'
   8    16        EXT_STMT                                                 
        17      > THROW                                         0          !0
  10    18*       JMP                                                      ->20
        19  E > > CATCH                                        20          'Exception', !1
  15    20    >   EXT_STMT                                                 
        21      > RETURN                                                   1

hellobranch: #  0; line:     2-    2; sop:     0; eop:     4; out1:   5; out2:  20
branch: #  5; line:     5-    5; sop:     5; eop:    12; out1:  -2
branch: # 13; line:     6-    6; sop:    13; eop:    13; out1:  14; out2:  -2
branch: # 14; line:     7-    8; sop:    14; eop:    17; out1:  -2
branch: # 19; line:    10-   10; sop:    19; eop:    19; out1:  20; out2:  -2
branch: # 20; line:    15-   15; sop:    20; eop:    21; out1:  -2
path #1: 0, 5, 
path #2: 0, 20, 
path #3: 13, 14, 
path #4: 19, 20, 

Fatal error: Uncaught exception 'Exception' with message 'Raaaa' in /home/derick/dev/php/derickr-xdebug/tests/bug01089.php on line 5

Exception: Raaaa in /home/derick/dev/php/derickr-xdebug/tests/bug01089.php on line 5

Call Stack:
    0.0014          0   1. {main}() /home/derick/dev/php/derickr-xdebug/tests/bug01089.php:0

opcode-on.txt (3,458 bytes)   
opcode-off.txt (3,576 bytes)   
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 5, Position 2 = 24
Branch analysis from position: 5
Jump found. Position 1 = -2
Branch analysis from position: 24
Jump found. Position 1 = -2
Found catch point at position: 16
Branch analysis from position: 16
Jump found. Position 1 = 17, Position 2 = -2
Branch analysis from position: 17
Jump found. Position 1 = -2
Found catch point at position: 22
Branch analysis from position: 22
Jump found. Position 1 = 23, Position 2 = -2
Branch analysis from position: 23
Jump found. Position 1 = 24
Branch analysis from position: 24
filename:       /home/derick/dev/php/derickr-xdebug/tests/bug01089.php
function name:  (null)
number of ops:  26
compiled vars:  !0 = $e, !1 = $e1
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   EXT_STMT                                                 
         1        EXT_FCALL_BEGIN                                          
         2        DO_FCALL                                      0  $0      'php_sapi_name'
         3        EXT_FCALL_END                                            
         4      > JMPZ                                                     $0, ->24
   3     5    >   NOP                                                      
   4     6        NOP                                                      
   5     7        EXT_STMT                                                 
         8        FETCH_CLASS                                   0  :1      'Exception'
         9        EXT_FCALL_BEGIN                                          
        10        NEW                                              $2      :1
        11        SEND_VAL                                                 'Raaaa'
        12        DO_FCALL_BY_NAME                              1          
        13        EXT_FCALL_END                                            
        14      > THROW                                         0          $2
   6    15*       JMP                                                      ->21
        16  E > > CATCH                                        21          'Exception', !0
   7    17    >   EXT_STMT                                                 
        18        ECHO                                                     'hello'
   8    19        EXT_STMT                                                 
        20      > THROW                                         0          !0
  10    21*       JMP                                                      ->23
        22  E > > CATCH                                        23          'Exception', !1
  13    23    > > JMP                                                      ->24
  15    24    >   EXT_STMT                                                 
        25      > RETURN                                                   1

hellobranch: #  0; line:     2-    2; sop:     0; eop:     4; out1:   5; out2:  24
branch: #  5; line:     3-    5; sop:     5; eop:    14; out1:  -2
branch: # 16; line:     6-    6; sop:    16; eop:    16; out1:  17; out2:  -2
branch: # 17; line:     7-    8; sop:    17; eop:    20; out1:  -2
branch: # 22; line:    10-   10; sop:    22; eop:    22; out1:  23; out2:  -2
branch: # 23; line:    13-   13; sop:    23; eop:    23; out1:  24
branch: # 24; line:    15-   15; sop:    24; eop:    25; out1:  -2
path #1: 0, 5, 
path #2: 0, 24, 
path #3: 16, 17, 
path #4: 22, 23, 24, 
opcode-off.txt (3,576 bytes)   
xdebug-off-opcache-off.txt (2,734 bytes)   
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 2, Position 2 = 14
Branch analysis from position: 2
Jump found. Position 1 = -2
Branch analysis from position: 14
Jump found. Position 1 = -2
Found catch point at position: 8
Branch analysis from position: 8
Jump found. Position 1 = 9, Position 2 = -2
Branch analysis from position: 9
Jump found. Position 1 = -2
Found catch point at position: 12
Branch analysis from position: 12
Jump found. Position 1 = 13, Position 2 = -2
Branch analysis from position: 13
Jump found. Position 1 = 14
Branch analysis from position: 14
filename:       /home/derick/dev/php/derickr-xdebug/tests/bug01089.php
function name:  (null)
number of ops:  15
compiled vars:  !0 = $e, !1 = $e1
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   DO_FCALL                                      0  $0      'php_sapi_name'
         1      > JMPZ                                                     $0, ->14
   5     2    >   FETCH_CLASS                                   0  :1      'Exception'
         3        NEW                                              $2      :1
         4        SEND_VAL                                                 'Raaaa'
         5        DO_FCALL_BY_NAME                              1          
         6      > THROW                                         0          $2
   6     7*       JMP                                                      ->11
         8  E > > CATCH                                        11          'Exception', !0
   7     9    >   ECHO                                                     'hello'
   8    10      > THROW                                         0          !0
  10    11*       JMP                                                      ->13
        12  E > > CATCH                                        13          'Exception', !1
  13    13    > > JMP                                                      ->14
  15    14    > > RETURN                                                   1

hellobranch: #  0; line:     2-    2; sop:     0; eop:     1; out1:   2; out2:  14
branch: #  2; line:     5-    5; sop:     2; eop:     6; out1:  -2
branch: #  8; line:     6-    6; sop:     8; eop:     8; out1:   9; out2:  -2
branch: #  9; line:     7-    8; sop:     9; eop:    10; out1:  -2
branch: # 12; line:    10-   10; sop:    12; eop:    12; out1:  13; out2:  -2
branch: # 13; line:    13-   13; sop:    13; eop:    13; out1:  14
branch: # 14; line:    15-   15; sop:    14; eop:    14; out1:  -2
path #1: 0, 2, 
path #2: 0, 14, 
path #3: 8, 9, 
path #4: 12, 13, 14, 
xdebug-off-opcache-off.txt (2,734 bytes)   
xdebug-off-opcache-on.txt (2,438 bytes)   
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 2, Position 2 = 12
Branch analysis from position: 2
Jump found. Position 1 = -2
Branch analysis from position: 12
Jump found. Position 1 = -2
Found catch point at position: 7
Branch analysis from position: 7
Jump found. Position 1 = 8, Position 2 = -2
Branch analysis from position: 8
Jump found. Position 1 = -2
Found catch point at position: 11
Branch analysis from position: 11
Jump found. Position 1 = 12, Position 2 = -2
Branch analysis from position: 12
filename:       /home/derick/dev/php/derickr-xdebug/tests/bug01089.php
function name:  (null)
number of ops:  13
compiled vars:  !0 = $e, !1 = $e1
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   DO_FCALL                                      0  $0      'php_sapi_name'
         1      > JMPZ                                                     $0, ->12
   5     2    >   FETCH_CLASS                                   0  :1      'Exception'
         3        NEW                                              $0      :1
         4        SEND_VAL                                                 'Raaaa'
         5        DO_FCALL_BY_NAME                              1          
         6      > THROW                                         0          $0
   6     7  E > > CATCH                                        10          'Exception', !0
   7     8    >   ECHO                                                     'hello'
   8     9      > THROW                                         0          !0
  15    10*       RETURN                                                   1
  10    11  E > > CATCH                                        12          'Exception', !1
  15    12    > > RETURN                                                   1

hellobranch: #  0; line:     2-    2; sop:     0; eop:     1; out1:   2; out2:  12
branch: #  2; line:     5-    5; sop:     2; eop:     6; out1:  -2
branch: #  7; line:     6-    6; sop:     7; eop:     7; out1:   8; out2:  -2
branch: #  8; line:     7-    8; sop:     8; eop:     9; out1:  -2
branch: # 11; line:    10-   10; sop:    11; eop:    11; out1:  12; out2:  -2
branch: # 12; line:    15-   15; sop:    12; eop:    12; out1:  -2
path #1: 0, 2, 
path #2: 0, 12, 
path #3: 7, 8, 
path #4: 11, 12, 
xdebug-off-opcache-on.txt (2,438 bytes)   
Operating System
PHP Version5.6.0-5.6.4

Activities

edrjoe

2014-11-20 14:26

reporter   ~0002914

Actually, this appears to happen with a host of different native function calls:

php_uname()
php_ini_loaded_file()

both cause the same error.

derick

2015-01-05 23:03

administrator   ~0002957

Last edited: 2015-01-05 23:06

I can reproduce this, and have pushed a test file (tests/bug01089.phpt) to
https://github.com/derickr/xdebug/tree/issue1089-error-handler

From what I can see, there are different oparrays being generated for opcache.enable_cli=1 vs opcache.enable_cli=0 (with no other settings changes). I've added the different opcode dumps coming out of VLD for these both cases, as well as with xdebug off for each too.

I can't figure out why this goes wrong though, as no valgrind warnings shows up (not even with USE_ZEND_ALLOC=0).

derick

2015-01-07 10:26

administrator   ~0002963

This turns out not to be a bug in Xdebug, but in opcache. I can reproduce this on the command line by putting your code in a file (1089.php) and running on the command line:

php -e -n -dzend_extension=opcache.so -dopcache.enable_cli=1 1089.php

-n disables all INI settings (including loading opcache and xdebug)
-e enables "extended information" for use with profilers

With the latter turned on, apparently, when Xinchem from Zend looked at it, he found:


the problem is:

<?php
try {
// ZEND_EXT_STMT
try {
// ZEND_EXT_STMT
throw..

in zend_update_ext_info which is called in pass_two, the first
EXT_STMT will became a NOP opline

thus, op_array->try_catch_array[0]->try_op is point to a NOP block,
which will be removed in cfg optimization.

I'm closing this issue, and a fix for opcache is on the way too.

Issue History

Date Modified Username Field Change
2014-11-20 14:13 edrjoe New Issue
2014-11-20 14:26 edrjoe Note Added: 0002914
2015-01-05 23:03 derick Note Added: 0002957
2015-01-05 23:03 derick Assigned To => derick
2015-01-05 23:03 derick Status new => acknowledged
2015-01-05 23:03 derick File Added: opcode-on.txt
2015-01-05 23:03 derick File Added: opcode-off.txt
2015-01-05 23:06 derick File Added: xdebug-off-opcache-off.txt
2015-01-05 23:06 derick File Added: xdebug-off-opcache-on.txt
2015-01-05 23:06 derick Note Edited: 0002957
2015-01-07 10:26 derick Note Added: 0002963
2015-01-07 10:26 derick Status acknowledged => resolved
2015-01-07 10:26 derick Resolution open => no change required
2016-07-31 12:36 derick Category Usage problems => Usage problems (Crashes)
2016-07-31 12:38 derick Category Usage problems (Crashes) => Usage problems (Wrong Results)
2020-03-12 16:35 derick Category Usage problems (Wrong Results) => Variable Display
2020-03-12 16:38 derick Category Variable Display => Uncategorized