View Issue Details

IDProjectCategoryView StatusLast Update
0002349XdebugStep Debuggingpublic2025-06-05 16:51
Reporterlcarilla Assigned Toderick  
PrioritynormalSeverityminorReproducibilityhave not tried
Status feedbackResolutionopen 
Summary0002349: https://github.com/xdebug/xdebug/commit/3bb2937e94dfcea6359e9f745e534e2049b2d45d breaks throwing exceptions in nested generators
Description

For the code in the "Steps To Reproduce" section, php with xdebug segfaults.
I did some debugging, it turns out to be this commit.
Interesting side note: i could not reproduce the "demo" leading to the heap corruption error that led to this fix commit being made :)

Steps To Reproduce
<?php
 function repro(
    ) {
        $b = 1;
        foreach (layer1() as $a) {
        }
    }

     function layer1(
    ): Generator {
        yield 1;
        yield from layer2();
    }

     function layer2(
    ): Generator
    {
        throw new \Exception("some random exception");
        yield 1;
    }
repro();
TagsNo tags attached.
Operating SystemLinux
PHP Version8.4-dev

Activities

derick

2025-05-20 18:18

administrator   ~0007288

How do you run this to make it segfault?

When running this on the command line in the following ways, I can't reproduce this:

XDEBUG_MODE=develop valgrind php /tmp/2349/bug02349.inc 

And valgrind shows no warnings either.

juancasanova

2025-05-23 08:35

reporter   ~0007293

I'm pretty sure I've got the same error as lcarilla. I haven't been able to reduce it to an actually small example, but when there is an exception reading messages from RabbitMQ with Xdebug active, it gives a segfault (Symfony uses generators for this, that's why I believe we are talking about the same error).

I have prepared a minimal Symfony project to reproduce the issue: https://github.com/juanmcasanova/xdebug-2349

If you need anything else from me (or that I create a new issue), just let me know!

juancasanova

2025-05-23 08:40

reporter   ~0007294

Sorry, forgot to include my PHP version information:

PHP 8.3.21 (cli) (built: May 21 2025 23:17:35) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.3.21, Copyright (c) Zend Technologies
with Zend OPcache v8.3.21, Copyright (c), by Zend Technologies
with Xdebug v3.4.3, Copyright (c) 2002-2025, by Derick Rethans

derick

2025-06-02 14:51

administrator   ~0007297

@Juancasanova: How do I run that Symfony project to reproduce? I know nothing about Symfony, and running the commands in the README still gives me errors:

2349$ php bin/console messenger:consume async -vv

 [OK] Consuming messages from transport "async".                                

 // The worker will automatically exit once it has received a stop signal via   
 // the messenger:stop-workers command.                                         

 // Quit the worker with CONTROL-C.                                             

[critical] Error thrown while running command "messenger:consume async -vv". Message: "Could not connect to the AMQP server. Please verify the provided DSN."

In AmqpReceiver.php line 66:

  [Symfony\Component\Messenger\Exception\TransportException]             
  Could not connect to the AMQP server. Please verify the provided DSN.  

Exception trace:
  at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:66
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->getEnvelope() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:47
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->getFromQueues() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:41
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->get() at /tmp/2349/xdebug-2349/vendor/symfony/messenger/Worker.php:111
 Symfony\Component\Messenger\Worker->run() at /tmp/2349/xdebug-2349/vendor/symfony/messenger/Command/ConsumeMessagesCommand.php:260
 Symfony\Component\Messenger\Command\ConsumeMessagesCommand->execute() at /tmp/2349/xdebug-2349/vendor/symfony/console/Command/Command.php:279
 Symfony\Component\Console\Command\Command->run() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:1094
 Symfony\Component\Console\Application->doRunCommand() at /tmp/2349/xdebug-2349/vendor/symfony/framework-bundle/Console/Application.php:123
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:342
 Symfony\Component\Console\Application->doRun() at /tmp/2349/xdebug-2349/vendor/symfony/framework-bundle/Console/Application.php:77
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:193
 Symfony\Component\Console\Application->run() at /tmp/2349/xdebug-2349/vendor/symfony/runtime/Runner/Symfony/ConsoleApplicationRunner.php:49
 Symfony\Component\Runtime\Runner\Symfony\ConsoleApplicationRunner->run() at /tmp/2349/xdebug-2349/vendor/autoload_runtime.php:29
 require_once() at /tmp/2349/xdebug-2349/bin/console:15

In Connection.php line 491:

  [AMQPException]                                                        
  Could not connect to the AMQP server. Please verify the provided DSN.  

Exception trace:
  at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/Connection.php:491
 Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection->channel() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/Connection.php:549
 Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection->clearWhenDisconnected() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/Connection.php:426
 Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection->get() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:54
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->getEnvelope() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:47
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->getFromQueues() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:41
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->get() at /tmp/2349/xdebug-2349/vendor/symfony/messenger/Worker.php:111
 Symfony\Component\Messenger\Worker->run() at /tmp/2349/xdebug-2349/vendor/symfony/messenger/Command/ConsumeMessagesCommand.php:260
 Symfony\Component\Messenger\Command\ConsumeMessagesCommand->execute() at /tmp/2349/xdebug-2349/vendor/symfony/console/Command/Command.php:279
 Symfony\Component\Console\Command\Command->run() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:1094
 Symfony\Component\Console\Application->doRunCommand() at /tmp/2349/xdebug-2349/vendor/symfony/framework-bundle/Console/Application.php:123
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:342
 Symfony\Component\Console\Application->doRun() at /tmp/2349/xdebug-2349/vendor/symfony/framework-bundle/Console/Application.php:77
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:193
 Symfony\Component\Console\Application->run() at /tmp/2349/xdebug-2349/vendor/symfony/runtime/Runner/Symfony/ConsoleApplicationRunner.php:49
 Symfony\Component\Runtime\Runner\Symfony\ConsoleApplicationRunner->run() at /tmp/2349/xdebug-2349/vendor/autoload_runtime.php:29
 require_once() at /tmp/2349/xdebug-2349/bin/console:15

In Connection.php line 489:

  [AMQPConnectionException]                                         
  Socket error: could not connect to host, a socket error occurred  

Exception trace:
  at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/Connection.php:489
 AMQPConnection->connect() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/Connection.php:489
 Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection->channel() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/Connection.php:549
 Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection->clearWhenDisconnected() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/Connection.php:426
 Symfony\Component\Messenger\Bridge\Amqp\Transport\Connection->get() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:54
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->getEnvelope() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:47
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->getFromQueues() at /tmp/2349/xdebug-2349/vendor/symfony/amqp-messenger/Transport/AmqpReceiver.php:41
 Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpReceiver->get() at /tmp/2349/xdebug-2349/vendor/symfony/messenger/Worker.php:111
 Symfony\Component\Messenger\Worker->run() at /tmp/2349/xdebug-2349/vendor/symfony/messenger/Command/ConsumeMessagesCommand.php:260
 Symfony\Component\Messenger\Command\ConsumeMessagesCommand->execute() at /tmp/2349/xdebug-2349/vendor/symfony/console/Command/Command.php:279
 Symfony\Component\Console\Command\Command->run() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:1094
 Symfony\Component\Console\Application->doRunCommand() at /tmp/2349/xdebug-2349/vendor/symfony/framework-bundle/Console/Application.php:123
 Symfony\Bundle\FrameworkBundle\Console\Application->doRunCommand() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:342
 Symfony\Component\Console\Application->doRun() at /tmp/2349/xdebug-2349/vendor/symfony/framework-bundle/Console/Application.php:77
 Symfony\Bundle\FrameworkBundle\Console\Application->doRun() at /tmp/2349/xdebug-2349/vendor/symfony/console/Application.php:193
 Symfony\Component\Console\Application->run() at /tmp/2349/xdebug-2349/vendor/symfony/runtime/Runner/Symfony/ConsoleApplicationRunner.php:49
 Symfony\Component\Runtime\Runner\Symfony\ConsoleApplicationRunner->run() at /tmp/2349/xdebug-2349/vendor/autoload_runtime.php:29
 require_once() at /tmp/2349/xdebug-2349/bin/console:15

messenger:consume [-l|--limit LIMIT] [-f|--failure-limit FAILURE-LIMIT] [-m|--memory-limit MEMORY-LIMIT] [-t|--time-limit TIME-LIMIT] [--sleep SLEEP] [-b|--bus BUS] [--queues QUEUES] [--no-reset] [--all] [--keepalive [KEEPALIVE]] [--] [<receivers>...]

acran

2025-06-05 10:45

reporter   ~0007300

I was able to create a reproducer for this - and probably also https://bugs.xdebug.org/view.php?id=2350 and https://bugs.xdebug.org/view.php?id=2352
Unfortunately it is not really minimal yet since it uses Twig but trying to extract the crashing code any further always failed to reproduce. But now it at least crashes reliably...

Since it was so hard to pin done the exact crashing conditions I put the code inside a reproducer repo that can simply be opened in vscode devcontainers / codespaces: https://github.com/acran/xdebug-2349-reproducer

The code example is
<code>
<?php

use Twig\Environment;
use Twig\Loader\ArrayLoader;

require_once DIR . '/vendor/autoload.php';

$loader = new ArrayLoader([
'test' => '{{ user.name }}',
]);
$twig = new Environment($loader);

class User {
public function getName() {
// throw an Exception while rendering
// in \Twig\Template::doDisplay()
throw new Exception();
}
}

$user = new User();

try {
// set a breakpoint on the following line and step over it
$twig->render('test', ['user' => $user]);

echo "we should never come here\n";

} catch (Throwable $e) {
echo "we should end up here due to the thrown Exception\n";
} finally {
echo "this should always be reached\n";
}

</code>

The crash only occurs when an Exception is thrown within Twig\Template::doDisplay() (https://github.com/twigphp/Twig/blob/285123877d4dd97dd7c11842ac5fb7e86e60d81d/src/Template.php#L526-L534) (which is implemented by a dynamically generated class for the rendered template).
It is called from Twig\Template::yield() (https://github.com/twigphp/Twig/blob/285123877d4dd97dd7c11842ac5fb7e86e60d81d/src/Template.php#L401-L403):
<code>
try {
yield from $this->doDisplay($context, $blocks);
} catch (Error $e) {
</code>

Both methods are generators which puts the Exception in the context of nested generators.

More things I noticed:

  • the crash occurs only with xdebug 3.4.3, downgrading to 3.4.2 works fine
  • reproducible with PHP 8.2, 8.3 and 8.4 (change the versions in Dockerfile to test it)
  • crash only occurs if xdebug.mode includes 'develop'

derick

2025-06-05 16:51

administrator   ~0007303

Thanks, I'll see if this is enough info to reproduce this in the next few days, and then also hopefully fix it.

Issue History

Date Modified Username Field Change
2025-05-19 20:01 lcarilla New Issue
2025-05-20 18:10 derick Steps to Reproduce Updated
2025-05-20 18:18 derick Assigned To => derick
2025-05-20 18:18 derick Status new => feedback
2025-05-20 18:18 derick Note Added: 0007288
2025-05-23 08:35 juancasanova Note Added: 0007293
2025-05-23 08:40 juancasanova Note Added: 0007294
2025-06-02 14:51 derick Note Added: 0007297
2025-06-05 10:45 acran Note Added: 0007300
2025-06-05 10:45 acran File Added: xdebug-2349-reproducer-master.zip
2025-06-05 16:51 derick Note Added: 0007303