View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002191 | Xdebug | Step Debugging | public | 2023-07-31 11:12 | 2023-07-31 13:07 |
Reporter | derick | Assigned To | derick | ||
Priority | normal | Severity | minor | Reproducibility | have not tried |
Status | closed | Resolution | fixed | ||
Target Version | 3.2dev | Fixed in Version | 3.2dev | ||
Summary | 0002191: Add warning when opcache is loaded after xdebug | ||||
Description | This came from https://github.com/xdebug/vscode-php-debug/issues/919 where breakpoints where not resolved. The full explanation: I spend some time delving into this, and at first I could not reproduce this. On my side (Linux, PHP 8.1/8.2) with php -S the behaviour was always right, with the breakpoints being resolved for each request through the dev server. When I had another good look at your phpinfo() output PDF file, I noticed:
This has OPcache loaded after Xdebug, which the documentation says you shouldn't do:
And indeed, when I switched the loading order of the two zend extensions from:
to
I could reproduce this issue. Both Xdebug and OPcache override PHP's "compile a file" handler. Xdebug's uses this so that it can analyse newly loaded files for lines of code that can have breakpoints on it, so that it then can then resolve them. Before doing it's magic, it calls the already present handler. OPcache uses it to see if a file that is being parsed for a second time, and it is in its cache, it doesn't compile it again by not calling the already present handler. If OPcache is first loaded, and then Xdebug, the following happens:
This means that when PHP runs the "compile this file" logic, it first calls xdebug_compile_file, which then calls opcache_compile_file and all is well. If OPcache is loaded last, the process is reversed:
When PHP then runs the "compile this file" logic, it calls opcache_compile first. This checks whether it has seen the file already, and if not, calls the previous handler (xdebug_compile_file), but if it has seen the file already (the second request through a php -S server) it does not call the previous compile file handler. Normally, that is what you want, as compiling files is expensive. However, because it does not call the previous file handler, that means that xdebug_compile_file does not get run, which in turn means it doesn't know anything about which lines of code can have breakpoints on them. This is not something that Xdebug can fix. There are workarounds:
Curiously, your phpinfo() output allegedly already shows the right order (/opt/homebrew/etc/php/8.2/conf.d/ext-opcache.ini, /opt/homebrew/etc/php/8.2/conf.d/xdebug.ini), but I can not tell if your PHP actually loads them in the order — the phpinfo() output indicates that it doesn't — or whether there is another place where the extension gets loaded (sometimes launch.json adds the -dzend_extension=xdebug part. Personally, I usually name the xdebug.ini file 99-xdebug.ini to enforce the sorting order — it is also possible that OSX's file system does not support an actual ordering here. If that is the case, you should create one ini file which loads both extensions:
| ||||
Tags | No tags attached. | ||||
Operating System | |||||
PHP Version | 8.2.0-8.2.9 | ||||
Date Modified | Username | Field | Change |
---|---|---|---|
2023-07-31 11:12 | derick | New Issue | |
2023-07-31 13:07 | derick | Assigned To | => derick |
2023-07-31 13:07 | derick | Status | new => closed |
2023-07-31 13:07 | derick | Resolution | open => fixed |
2023-07-31 13:07 | derick | Fixed in Version | => 3.2dev |
2023-07-31 13:07 | derick | Note Added: 0006614 |