MantisBT - Xdebug
View Issue Details
0000938XdebugFeature/Change requestpublic2013-03-25 12:302018-07-09 08:52
najcik 
derick 
normalmajoralways
closedfixed 
2.2.2 
2.7.0dev2.7.0alpha1 
Linux
5.3.3
0000938: Unreliable debugging of forking processes
If you decide to remote debug code that use pnctl_fork() function at least both eclipse and xdc 1.0b5 either crash or don't stop at desired breaking points.
Just assume I have a working environment that allows for remote debugging e.g.:
a php-cli that is configured to remotely trigger a debugging session at a debug client (eclipse 4.2/pdt and xdc1.0b5 in my case)

Consider following script:

01: <?php
02: echo "started\n";
03: if ($child = pcntl_fork()) {
04: sleep(5);
05: print "hello from parent\n"; //breakpoint no. 1 here
06: $status;
07: pcntl_waitpid($child, $status);
08: print "finished\n";
09: } else {
10: print "hello from child\n"; //breakpoint no. 2 here
11:}

Let's say we set the breakpoints at line 05 and 10.
Apparently the first breakpoint to occur is at line 10. If we resume execution after more the 5 seconds of investigation it's not possible to stop at line 5.

 
I assume that xdebug does not provide enough information back to the client so it knows it actually talks with more then one process. As far as I know when forking occurs the open connections are shared between the forked processes. So the open connection to the IDE / xdebug client is shared between the two forked processes too and can make a lot of confusion in the clients.
This situation can be observed in Eclipse w/PDT because when it switches to debug perspective it always indicates it talks to a single process even though you might have forked many.
This is completely different when you debug a webpage that spawns many php cgi instances which response to multiple ajax calls and this situaltion is well handled in Eclipse.

I've tried earlier versions of xdebug too. The same behavior.
No tags attached.
? xdebug-pcntl-fork-reference-implementation.php (4,637) 2018-01-20 14:12
https://bugs.xdebug.org/file_download.php?file_id=410&type=bug
? xdebug-pcntl-fork-reference-implementation-0.php (6,532) 2018-02-07 21:05
https://bugs.xdebug.org/file_download.php?file_id=413&type=bug
Issue History
2013-03-25 12:30najcikNew Issue
2014-02-27 19:49derickNote Added: 0002715
2014-02-27 19:49derickCategoryDebug client (console) => Feature/Change request
2016-03-10 21:11jimpNote Added: 0003568
2016-12-12 00:16derickNote Added: 0004030
2016-12-12 00:16derickAssigned To => derick
2016-12-12 00:16derickStatusnew => confirmed
2016-12-13 21:27jimpNote Added: 0004046
2017-02-22 01:19cmqlabsNote Added: 0004219
2017-02-24 10:56derickNote Added: 0004220
2018-01-04 19:37brad@rhift.comNote Added: 0004548
2018-01-19 11:16derickTarget Version => 2.7.0dev
2018-01-20 14:12brad@rhift.comFile Added: xdebug-pcntl-fork-reference-implementation.php
2018-01-20 14:14brad@rhift.comNote Added: 0004567
2018-02-07 21:05brad@rhift.comFile Added: xdebug-pcntl-fork-reference-implementation-0.php
2018-03-30 11:33derickNote Added: 0004623
2018-03-30 11:33derickStatusconfirmed => closed
2018-03-30 11:33derickResolutionopen => fixed
2018-03-30 11:33derickFixed in Version => 2.7.0dev
2018-03-31 06:00jimpNote Added: 0004628
2018-04-01 14:47derickFixed in Version2.7.0dev => 2.7.0alpha1
2018-04-05 13:37najcikNote Added: 0004631
2018-07-09 08:48leonxingNote Added: 0004677
2018-07-09 08:48leonxingNote Edited: 0004677bug_revision_view_page.php?bugnote_id=4677#r447
2018-07-09 08:50leonxingNote Edited: 0004677bug_revision_view_page.php?bugnote_id=4677#r448
2018-07-09 08:52leonxingNote Edited: 0004677bug_revision_view_page.php?bugnote_id=4677#r449

Notes
(0002715)
derick   
2014-02-27 19:49   
Changing this to a feature request, but I have no idea on how to do this (yet).
(0003568)
jimp   
2016-03-10 21:11   
I am having this same problem. I am finding the debugging works, even though the debugger is technically reacting to two different processes after the fork. But when the parent process exits I lose the XDebug socket to my client and debugging is over. Therefore my PHP daemon CLI app can only be debugged right up until the first process exits after the pnctl_fork() call.

Userland control of enabling and disabling the debugger (and I assume the profiler is affected, too) would allow my program to restart the debugger after the fork. I am already doing that for DB connections, and that feature would also allow me to determine a separate port for the daemon process and the child process.
(0004030)
derick   
2016-12-12 00:16   
I think I have an idea on how to solve this, but I won't want to commit to a version for this yet.
(0004046)
jimp   
2016-12-13 21:27   
Derick,

Thank you for the attention to this issue. I am available to help test the solution, if you need feedback. I think it is sufficient to allow a forked child to establish a new connection manually, which also could allow for more powerful debugging. For example, a PHP application could connect to the debug listener on demand in response to application-specific criteria.
(0004219)
cmqlabs   
2017-02-22 01:19   
Do you have any update on this feature? Do you know when it will be available?
(0004220)
derick   
2017-02-24 10:56   
Sorry, I've no idea yet.
(0004548)
brad@rhift.com   
2018-01-04 19:37   
Hey Derick - can this feature be funded? If so, I'd be *very* interested in talking to you about what you think that it would take to get this done from a financial perspective. This would be extremely useful. Thanks!
(0004567)
brad@rhift.com   
2018-01-20 14:14   
Hi Derick - attached is a reference implementation to check an implementation of this feature request against. Thanks for taking a look!
(0004623)
derick   
2018-03-30 11:33   
This issue has been addressed and merged into Xdebug's master branch on Git. It will form part of the 2.7.0alpha1 release. It's implementation was generously supported by @brad.
(0004628)
jimp   
2018-03-31 06:00   
I looked at the code changes and I think this will fix my problem as well. If I'm understanding correctly, Xdebug will now compare the PID to the previously known PID of an established debugging session, so a new connection will be automatically made for the child process and therefore avoid having a shared socket descriptor between processes that gets closed when any process exits.

I'm really looking forward to trying this out. Thanks Derick and Brad!
(0004631)
najcik   
2018-04-05 13:37   
Thank you!
(0004677)
leonxing   
2018-07-09 08:48   
(edited on: 2018-07-09 08:52)
this fix(2.7.0alpha1) brings other bug

https://github.com/swoole/swoole-src [^]
swoole http svr cannot break with xdebug 2.7.0alpha1(in child process)
bug xdebug 2.6.0 is ok(both in parent and child processes)
here is an example <<simple_http.php>>
-------------------------------------------------------
<?php
xdebug_break();
$http = new swoole_http_server('0.0.0.0', 9502); //parent process can break with both 2.6.0&2.7.0alpha
$conf = [
    'pid_file' => __DIR__ . '/server.pid',
    'worker_num' => 1,
    'max_request' => 10,
    'daemonize' => 0,
];
$http->set($conf);

$http->on('request', function ($request, $response) {
    xdebug_break(); //child process cannot break with 2.7.0alpha, but 2.6.0 is OK
    $response->header('Content-Type', 'text/html; charset=utf-8');
    $response->end('<h1>Hello Swoole. #' . rand(1000, 9999) . '</h1>');
});

$http->start();
----------------------------------------------------------
I do remote debug with phpstorm

1. phpstorm "Run/Debug Configurations",add "PHP Remote Debug",give it an arbitrary name,no other settings in this dialog

2. phpstorm
File | Settings | Languages & Frameworks | PHP | Servers
Name: simple_http(should be the same with serverName in PHP_IDE_CONFIG in step 3)
Host: your server ip
Port: your server port(9502 in this example)
Debugger: xdebug
select "Use path mappings"
and config the path mapping

3. before start(tell phpstorm to use which server configuration)
export PHP_IDE_CONFIG="serverName=simple_http"

4. start cmd
php -dxdebug.remote_enable=1 -dxdebug.remote_mode=jit -dxdebug.remote_port=9000 -dxdebug.remote_host=10.25.161.110 -dxdebug.remote_autostart=1 simple_http.php

it breaks in first xdebug_break()

but when i send
"curl http://127.0.0.1:9502" [^]
xdebug 2.6.0 can break in second xdebug_break()
xdebug 2.7.0alpha cannot break