swoole / swoole-src

🚀 Coroutine-based concurrency library for PHP
https://www.swoole.com
Apache License 2.0
18.33k stars 3.16k forks source link

Debugging Application with Xdebug #1681

Closed aftabnaveed closed 3 years ago

aftabnaveed commented 6 years ago

PHP Version 7.1.9

The documentation says that Swoole coroutine cannot be used with xdebug, while developling applications xdebug is very helpful tool. For smaller application it may not be a problem but larger applications makes it necessary to use it.

My question is how can I debug applications while still using Swoole Coroutines ?

matyhtf commented 6 years ago

Hi @aftabnaveed , Xdebug conflicts with swoole coroutine.

We are developing a coroutine tracking and debugging tool now. Will be released later

gouchaoer commented 6 years ago

amazing Is this debug tool compatible with xdebug? If so, it should be convenient to use it in phpstorm

sshymko commented 6 years ago

@matyhtf Wouldn't it be better to make Swoole and Xdebug compatible instead of creating a custom debug tool? Is it possible at all? Xdebug is a mature tool with excellent IDE support. It does not make sense to create yet another tool.

tarach commented 6 years ago

@sshymko I'm guessing it sounds a lot easier than it actually is unfortunately.

@matyhtf Please let us know when there will any alpha even available. I would love to try it. ~and thanks for swoole btw :)

sshymko commented 6 years ago

@tarach I bet it's very tricky if at all possible to make Swoole and Xdebug compatible. The only justification for the creation of a brand new debug tool is a complete architectural incompatibility of two technologies. I am not an expert in the PHP internals to judge that. Just wanted to make sure the subject matter experts @derickr - author of Xdebug - and PHP internals gurus @nikic or @dstogov are involved in the conversation.

derickr commented 6 years ago

If anything, you should probably base any debugging tool off the DBGp protocol, so that at least IDEs have instantaneous support for it, as it's the protocol that Xdebug uses: https://xdebug.org/docs-dbgp.php — feel free to reach out if you have questions regarding the protocol.

tarach commented 5 years ago

@derickr When you were developing xdebug how were you debugging your extensions? I mean Swoole clearly has a conflict with debuggers. I'm guessing its because they all use the same entrypoint to the PHP/Zend engine. If I were to trace that issue watching line by line PHP startup process ( just like your extension allows me to do with PHP scripts ) what tools should I use?

@matyhtf What kind of approach would you suggest for now? Does register_tick_function would work with Swoole ( I remember using it once or twice for debugging ) or maybe write code compatible with standard stack Apache / Nginx + PHP ?

derickr commented 5 years ago

@tarach export USE_ZEND_ALLOC=0 && export ZEND_DONT_UNLOAD_EXTENSIONS=1. And then use gdb as "Xdebug replacement" like gdb --args path/to/php script.php — it's command line based. You can set break points on functions with break functioname or break filename:linenumber. The trick is finding out where to set the breakpoint...

For debugging memory leaks and other issues, I'd use valgrind, like valgrind php script.php (tiny tutorial at https://derickrethans.nl/valgrind-null.html).

aftabnaveed commented 5 years ago

@matyhtf Has any progress been made in this regard? We really want to migrate from Swoole 2.0.x to Swoole 4.x but xdebug or debugging for that matter is a deal breaker for us at the moment.

er1z commented 5 years ago

Bump? Is this still at least on a roadmap?

eugenzaharia commented 5 years ago

Any progress to this feature?

nick-zh commented 5 years ago

Is there a way to disable coroutines? The doc states: https://www.swoole.co.uk/coroutine But when i do a ./configure --disable-coroutine i get:

configure: WARNING: unrecognized options: --disable-coroutine
sshymko commented 5 years ago

I'm with @nick-zh on providing the ability to disable coroutines for Xdebug compatibility purposes. In fact, stateful applications with mutable global state cannot utilize coroutines. Specialized coroutine-aware debugging tool would be irrelevant to them.

nick-zh commented 5 years ago

Anybody interested in using xdebug (only if you are not using coroutines), check out this issue: https://github.com/swoole/swoole-src/issues/2655 Thx again @mabu233

lihe6666 commented 4 years ago

Any progress to this feature?

nick-zh commented 4 years ago

@lihe6666 are you having trouble using https://github.com/swoole/sdebug ? The newest release / branch should also work with php:7.4

aftabnaveed commented 4 years ago

@nick-zh the documentation seems to be not very clear about it, what does it do? Does it replace xdebug? Does it support co-routines?

nick-zh commented 4 years ago

@aftabnaveed it does replace xdebug if you are using swoole, yes. As to co-routines, i can't say since i don't use them, sry. If you find out, please let us know :v:

huanghantao commented 4 years ago

@aftabnaveed Have you ever used xdebug? Sdebug is installed exactly the same way as xdebug. Perhaps you could first see how xdebug is used?

It is my ini configuration:

[root@592b0366acbf ~]# cat /etc/php.d/sdebug.ini
zend_extension=xdebug.so
xdebug.remote_enable = 1
xdebug.remote_autostart = 1
[root@592b0366acbf ~]#

If you want to debug remotely, it is my configuration:

/var/www/sdk # cat /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
[XDebug]
zend_extension=xdebug.so

xdebug.remote_autostart=1
xdebug.remote_host=host.docker.internal
xdebug.remote_port=9000
xdebug.remote_enable=1
lihe6666 commented 4 years ago

https://github.com/swoole/sdebug

Thank you.

juslintek commented 4 years ago

Seems like this is not working with IDE Key.

xdebug support => enabled
Support Xdebug on Patreon, GitHub, or as a business: https://xdebug.org/support
xdebug.auto_trace => Off => Off
xdebug.cli_color => 0 => 0
xdebug.collect_assignments => Off => Off
xdebug.collect_includes => On => On
xdebug.collect_params => 0 => 0
xdebug.collect_return => Off => Off
xdebug.collect_vars => Off => Off
xdebug.coverage_enable => On => On
xdebug.default_enable => On => On
xdebug.dump.COOKIE => no value => no value
xdebug.dump.ENV => no value => no value
xdebug.dump.FILES => no value => no value
xdebug.dump.GET => no value => no value
xdebug.dump.POST => no value => no value
xdebug.dump.REQUEST => no value => no value
xdebug.dump.SERVER => no value => no value
xdebug.dump.SESSION => no value => no value
xdebug.dump_globals => On => On
xdebug.dump_once => On => On
xdebug.dump_undefined => Off => Off
xdebug.file_link_format => no value => no value
xdebug.filename_format => no value => no value
xdebug.force_display_errors => Off => Off
xdebug.force_error_reporting => 0 => 0
xdebug.gc_stats_enable => Off => Off
xdebug.gc_stats_output_dir => /tmp => /tmp
xdebug.gc_stats_output_name => gcstats.%p => gcstats.%p
xdebug.halt_level => 0 => 0
xdebug.idekey => DOCKER-MYG2-BACKEND => DOCKER-MYG2-BACKEND
xdebug.max_nesting_level => 500 => 500
xdebug.max_stack_frames => -1 => -1
xdebug.overload_var_dump => 2 => 2
xdebug.profiler_append => Off => Off
xdebug.profiler_enable => Off => Off
xdebug.profiler_enable_trigger => On => On
xdebug.profiler_enable_trigger_value => no value => no value
xdebug.profiler_output_dir => /var/www/html/storage/cache/xdebug-profiles/ => /var/www/html/storage/cache/xdebug-profiles/
xdebug.profiler_output_name => cachegrind.out.%R.%p => cachegrind.out.%R.%p
xdebug.remote_addr_header => no value => no value
xdebug.remote_autostart => On => On
xdebug.remote_connect_back => Off => Off
xdebug.remote_cookie_expire_time => 3600 => 3600
xdebug.remote_enable => On => On
xdebug.remote_host => host.docker.internal => host.docker.internal
xdebug.remote_log => no value => no value
xdebug.remote_log_level => 7 => 7
xdebug.remote_mode => req => req
xdebug.remote_port => 9000 => 9000
xdebug.remote_timeout => 200 => 200
xdebug.scream => Off => Off
xdebug.show_error_trace => Off => Off
xdebug.show_exception_trace => Off => Off
xdebug.show_local_vars => Off => Off
xdebug.show_mem_delta => Off => Off
xdebug.trace_enable_trigger => Off => Off
xdebug.trace_enable_trigger_value => no value => no value
xdebug.trace_format => 0 => 0
xdebug.trace_options => 0 => 0
xdebug.trace_output_dir => /tmp => /tmp
xdebug.trace_output_name => trace.%c => trace.%c
xdebug.var_display_max_children => 128 => 128
xdebug.var_display_max_data => 512 => 512
xdebug.var_display_max_depth => 3 => 3
nick-zh commented 4 years ago

@juslintek just to make sure, you are using sdebug with the branch sdebug_2_9?

juslintek commented 4 years ago

@nick-zh I am using it, the thing is if I run sdebug. image If I set breakpoint lets to say at Authentication controller to check if it is fetching fresh request or one from memory. And I restart the whole server and it is not even starting it is stuck. Then I stop it and it starts. But after it starts if I run remote debug again it has no effect no matter how many requests I make, the breakpoint is never hit, even though that part I breakpoint is checked via middleware every request. With php-fpm it worked. With swoole and sdebug it doesn't.

P.S. I removed xdebug, because it was crashing my whole PC. :D

nick-zh commented 4 years ago

@juslintek alright thx, i will try to check this evening in a small test project if i can reproduce this. Have to be honest, didn't have to debug for a few weeks. But apart from getting it runnig for the first time, i had no problems.

juslintek commented 4 years ago

@nick-zh, well I'm using it inside a docker, maybe I should've mentioned that. :-) it is the latest ubuntu lt is, with the latest PHP 7.4.

nick-zh commented 4 years ago

@juslintek yeah i figured and you are running osx on host, i noticed the host.docker.internal :wink:

juslintek commented 4 years ago

@nick-zh Yes, I am, but I resolve that manually, that hostname points to the default gateway.

pavrip commented 3 years ago

So its 2020 now and apparently there is still no proper compatibility with Xdebug? I have just managed to install Swoole after a nightmare because of the terrible documentation and now I am still getting the same issue, I am trying to build a fantastic framework and I would love to build it on top of Swoole, but its very hard without a proper debugging tool

huanghantao commented 3 years ago

@pavrip

Can you use this? If there is a problem, I will try to solve it:

https://github.com/huanghantao/xdebug

nick-zh commented 3 years ago

@juslintek @pavrip sry guys i totally forgot to provide my findings. So this seems to work fine with the current sdebug version on swoole:4.5.2 i am using the following xdebug.ini settings:

zend_extension=xdebug.so
xdebug.profiler_enable_trigger=1
xdebug.remote_enable=on
xdebug.remote_autostart=off
xdebug.remote_connect_back=1
xdebug.idekey=PHPSTORM

Also you need to run the debug target in PHPStorm, before you start swoole. It seems if you start the debug target when swoole is already running, it doesn't work properly, at least for me.

@huanghantao if you have any improvements to sdebug, a PR to swoole/sdebug would be highly appreciated

juslintek commented 3 years ago

@nick-zh if you start xdebug before docker image is runned then it gets stuck forever and never finishes loading, even though no breakpoints are set. :D And it doesn't work for me, I have my swoole docker image listening on 5200 port and I setup remote server on phpstorm to listen on that port as well.

My ide key is DOCKER-MYG2-BACKEND. I set same in xdebug config and on PHPStorm. Basically I've set my configs like this:

zend_extension=xdebug.so
xdebug.remote_enable=on
xdebug.remote_autostart=off
xdebug.remote_connect_back=on
xdebug.remote_handler=dbgp
xdebug.remote_port=9000
xdebug.idekey=DOCKER-MYG2-BACKEND
xdebug.remote_host=host.docker.internal
xdebug.max_nesting_level=500
xdebug.profiler_enable_trigger=on
xdebug.profiler_output_dir=/var/www/html/storage/framework/cache/xdebug-profiles/
xdebug.remote_log=/var/www/html/storage/logs/xdebug-remote.log
xdebug.profiler_output_name=cachegrind.out.%R.%p
xdebug.coverage_enable=true

Remote log says it is connected to sdebug client. But guess PHPStorm xdebug client doesn't recognise it or something and does not display anything.

[269] Log opened at 2020-08-21 14:50:24
[269] I: Connecting to configured address/port: host.docker.internal:9000.
[269] I: Connected to client. :-)
[269] -> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///var/www/html/bin/laravels" language="PHP" xdebug:language_version="7.4.3" protocol_version="1.0" appid="269" idekey="DOCKER-MYG2-BACKEND"><engine version="2.9.3-dev"><![CDATA[Sdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2020 by Derick Rethans]]></copyright></init>

[269] <- eval -i 1 -- KHN0cmluZykoaW5pX2dldCgneGRlYnVnLmNvdmVyYWdlX2VuYWJsZScpLic7Jy5pbmlfZ2V0KCd4ZGVidWcucHJvZmlsZXJfZW5hYmxlJykuJzsnLmluaV9nZXQoJ3hkZWJ1Zy5yZW1vdGVfYXV0b3N0YXJ0JykuJzsnLmluaV9nZXQoJ3hkZWJ1Zy5yZW1vdGVfY29ubmVjdF9iYWNrJykuJzsnLmluaV9nZXQoJ3hkZWJ1Zy5yZW1vdGVfbW9kZScpKQ==
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="eval" transaction_id="1"><property type="string" size="10" encoding="base64"><![CDATA[MTswOzE7O3JlcQ==]]></property></response>

[269] <- feature_set -i 2 -n show_hidden -v 1
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="2" feature="show_hidden" success="1"></response>

[269] <- feature_set -i 3 -n max_depth -v 1
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="3" feature="max_depth" success="1"></response>

[269] <- feature_set -i 4 -n max_children -v 100
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="4" feature="max_children" success="1"></response>

[269] <- feature_set -i 5 -n extended_properties -v 1
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="5" feature="extended_properties" success="1"></response>

[269] <- feature_set -i 6 -n notify_ok -v 1
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="6" feature="notify_ok" success="1"></response>

[269] <- feature_set -i 7 -n resolved_breakpoints -v 1
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="feature_set" transaction_id="7" feature="resolved_breakpoints" success="1"></response>

[269] <- stdout -i 8 -c 1
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="stdout" transaction_id="8" success="1"></response>

[269] <- status -i 9
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="status" transaction_id="9" status="starting" reason="ok"></response>

[269] <- step_into -i 10
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="step_into" transaction_id="10" status="break" reason="ok"><xdebug:message filename="file:///var/www/html/vendor/hhxsv5/laravel-s/src/Swoole/Process/CustomProcessTrait.php" lineno="63"></xdebug:message></response>

[269] <- breakpoint_set -i 11 -t line -f file:///var/www/html/app/Http/Controllers/AppController.php -n 14
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="breakpoint_set" transaction_id="11" id="2690001" resolved="unresolved"></response>

[269] <- stack_get -i 12
[269] -> <response xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" command="stack_get" transaction_id="12"><stack where="Hhxsv5\LaravelS\LaravelS-&gt;Hhxsv5\LaravelS\Swoole\Process\{closure:/var/www/html/vendor/hhxsv5/laravel-s/src/Swoole/Process/CustomProcessTrait.php:62-72}" level="0" type="file" filename="file:///var/www/html/vendor/hhxsv5/laravel-s/src/Swoole/Process/CustomProcessTrait.php" lineno="63"></stack></response>

[269] <- run -i 13
[275] Log opened at 2020-08-21 14:50:27
[275] I: Connecting to configured address/port: host.docker.internal:9000.
[275] I: Connected to client. :-)
[275] -> <init xmlns="urn:debugger_protocol_v1" xmlns:xdebug="https://xdebug.org/dbgp/xdebug" fileuri="file:///var/www/html/artisan" language="PHP" xdebug:language_version="7.4.3" protocol_version="1.0" appid="275" idekey="DOCKER-MYG2-BACKEND"><engine version="2.9.3-dev"><![CDATA[Sdebug]]></engine><author><![CDATA[Derick Rethans]]></author><url><![CDATA[https://xdebug.org]]></url><copyright><![CDATA[Copyright (c) 2002-2020 by Derick Rethans]]></copyright></init>

P.S. I am using sdebug_2_9 branch.

After setting: remote_autostart=0 , remote_log is not even created.

P.S. My PhpStorm version:

PhpStorm 2020.2
Build #PS-202.6397.115, built on July 29, 2020
Runtime version: 11.0.7+10-b944.20 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 10.15.6
GC: ParNew, ConcurrentMarkSweep
Memory: 1979M
Cores: 16

P.S. telnet is also from that docker container is able to connect to PHPStorm debug client. Seems like PHPStorm debug client is not doing anything for some reason... And if I stop xdebug client it is not able to do it anymore, which means that it is connecting to correct debug client.

Basically it is really random and unstable, sometimes it works sometimes it doesn't. Sometimes it says mapping is bad and so on. But everything is fine. I create issue for same reason here: https://github.com/swoole/swoole-src/issues/3421

Even with PHP_IDE_CONFIG="serverName=myg2-app", it doesn't work, myg2-app is name of server connection.

So the only way I can use xdebug is write API tests for all endpoints and scenarios and run them with phpunit or something and add breakpoints where I want app to break.

Basically as long as you skip swoole server all is fine. Sdebug doesn't work with swoole server...

huanghantao commented 3 years ago

We recommend using https://github.com/swoole/yasd to debug

juber-nunes commented 3 years ago

@juslintek any luck on this? I'm also using laravel-s on a docker setup but unable to debug. Communication between container and IDE seems fine and even seems to start to capture something but it drops after a second or so.

juslintek commented 3 years ago

@juber-ivre it works randomly, you have to restart docker container or process or restart it, make sure no parallel connections exist and make sure ide accepts more then 4 xdebug connections. But usually what I do is just replay specific request from developer tools network tab. With phpunit there are no problems :-)

juslintek commented 3 years ago

We recommend using https://github.com/swoole/yasd to debug

It doesn't work with phpstorm, even tests fail. Left a issue regarding that: https://github.com/swoole/yasd/issues/95 as I see it doesn't work with VSCode as well: https://github.com/swoole/yasd/issues/94

And Sdebug does not support php8 :-( Its like a dead end. You have to fall back to cli coding... Thats a bad dev experience.

siddjain commented 3 years ago

curious if (and how) you were able to make yasd work with vs code?

Radiergummi commented 2 years ago

Any news on this front? Ditching XDebug is simply not an option. No other tool is going to get as much traction and IDE support. This is a show stopper...

aftabnaveed commented 2 years ago

Any news on this front? Ditching XDebug is simply not an option. No other tool is going to get as much traction and IDE support. This is a show stopper...

If you don't need the coroutines just disable it while debugging and the xdebug should work perfectly fine.

Radiergummi commented 2 years ago

If you don't need the coroutines just disable it while debugging and the xdebug should work perfectly fine.

No, it doesn't, sadly. We're running Laravel Octane on Swoole and XDebug won't connect to the IDE if running in Swoole. We had to build an awkward workaround to use the builtin PHP server in local development instead of Octane to be able to debug our application.

nprasath002 commented 6 months ago

Hi @Radiergummi , Sorry for reopening this conversation. But I am curious about what workaround you use to get xdebug working?

Radiergummi commented 6 months ago

No worries @nprasath002. So what we do is a bit awkward, but works: Basically, we use the built-in PHP web server instead of Octane/Swoole in locale development. That is, our entry point script checks the configured environment and either spawns php artisan octane:start in production, or php artisan serve in local development.
This allows us to use XDebug locally -- by simply not serving with Swoole. That carries the risk of not noticing a certain kind of bugs or memory leaks; that's another reason to have a rigorous testing schedule, and a staging environment, though.

I'd very much prefer XDebug to work in Swoole, but that's how it is right now.

set -e

role=${CONTAINER_ROLE:-web}
env=${APP_ENV:-production}

echo "Caching configuration for ${env}..."
php --define xdebug.mode=off artisan config:cache

if [ "$role" = "web" ]; then
    rpc_port=${WEB_RPC_PORT:-6001}
    listen_port=${WEB_LISTEN_PORT:-9000}
    max_requests=${WEB_MAX_REQUESTS:-500}
    worker_count=${WEB_WORKER_COUNT:-auto}

    php --define xdebug.mode=off artisan view:cache

    if [ "${env}" = "local" ]; then
        exec php /app/artisan serve \
            --port="${listen_port}" \
            --host=0.0.0.0 \
            "$@"
    else
        exec php /app/artisan octane:start \
            --max-requests="${max_requests}" \
            --workers="${worker_count}" \
            --rpc-port="${rpc_port}" \
            --port="${listen_port}" \
            --server=swoole \
            --host=0.0.0.0 \
            "$@"
    fi
fi
nprasath002 commented 6 months ago

Thanks @Radiergummi

alex-lx commented 6 months ago

Hi, any progress here? Our project uses coroutine, so not using swoole in dev is not a option.:-)

Radiergummi commented 6 months ago

Hi, any progress here? Our project uses coroutine, so not using swoole in dev is not a option.:-)

I know this sounds stupid, but you're probably better off wrapping that code in an if ($dev) block and run it synchronously. If debugger support lands in Swoole at all, it's a long way off, and you probably will need your debugger until then...