Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Segmentation fault occurs with console progress bar callback formatting #47107

Open
divineniiquaye opened this issue Jul 29, 2022 · 6 comments
Open

Comments

@divineniiquaye
Copy link

Symfony version(s) affected

All supported versions

Description

I am trying to add a text to the console's component progress bar current placeholder format. Unfortunately, it panicked with a segmentation fault.

I think this bug might occur with all supported versions of Symfony, but I encountered this issue with version 6.1 and PHP version 8.1.8.

I'll appreciate it, if this is fixed quickly, Thanks

How to reproduce

Using the SymfonyStyle class of the console component as $output:

$progress = $output->createProgressBar();
$progress->setPlaceholderFormatterDefinition(
    'current',
    fn (ProgressBar $bar) => 'Reading: '.$bar->getPlaceholderFormatterDefinition('current')($bar)
);

Possible Solution

The code written for the console's progress bar looks good, but can't tell for sure if it is a bug within the code or the PHP version used. The segmentation fault bug occured working in WSL 2.

Additional Context

No response

@xabbuh
Copy link
Member

xabbuh commented Jul 29, 2022

Can you create a small example application that allows to reproduce your issue?

@divineniiquaye
Copy link
Author

Can you create a small example application that allows to reproduce your issue?

use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\ArgvInput;
use Symfony\Component\Console\Output\ConsoleOutput;
use Symfony\Component\Console\Style\SymfonyStyle;

require __DIR__.'/vendor/autoload.php';

$output = new SymfonyStyle(new ArgvInput(), new ConsoleOutput());
$progress = $output->createProgressBar(20);
$progress->setPlaceholderFormatterDefinition(
    'current',
    fn (ProgressBar $bar) => 'Counting: '. $bar->getPlaceholderFormatterDefinition('current')($bar)
);

$progress->start();
for ($i=0; $i < 20; $i++) {
    $progress->advance();
    sleep(1);
}
$progress->finish();
$output->newLine();

If you do this at the point of setting a current placeholder format definition, the code will work

- $progress->setPlaceholderFormatterDefinition(
+ // $progress->setPlaceholderFormatterDefinition(
-    'current',
+   //'current',
-    fn (ProgressBar $bar) => 'Counting: '. $bar->getPlaceholderFormatterDefinition('current')($bar)
+    //fn (ProgressBar $bar) => 'Counting: '. $bar->getPlaceholderFormatterDefinition('current')($bar)
- );
+ //);

This bug has two different behaves, either it hungs (nothing happens), or a segmentation fault error is emitted.

@xabbuh
Copy link
Member

xabbuh commented Jul 29, 2022

Status: Reviewed

@alamirault
Copy link
Contributor

alamirault commented Jul 29, 2022

With this code, you make a recursive loop on current formatter.

Instead using getPlaceholderFormatterDefinition('current') when setPlaceholderFormatterDefinition('current), you maybe write something like this

$progress->setPlaceholderFormatterDefinition(
  'current',
  fn (ProgressBar $bar) => 'Reading: '.str_pad($bar->getProgress(), $bar->getStepWidth(), ' ', \STR_PAD_LEFT)
)

(Definition of current in ProgressBar https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Console/Helper/ProgressBar.php#L540)

However with this way you cannot have same output as default because getStepWidth is private.

@alamirault
Copy link
Contributor

Another approach is to not use same formatter name:

$progress->setPlaceholderFormatterDefinition(
      'my_current',
      fn(ProgressBar $bar) => 'Reading: '.$bar->getPlaceholderFormatterDefinition('current')($bar)
  );
$progress->setFormat('%my_current%')

You can find default ProgressBar formats here: https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Console/Helper/ProgressBar.php#L551

@divineniiquaye
Copy link
Author

divineniiquaye commented Jul 29, 2022

@alamirault I've tried your approach before creating this issue, I want to keep using the existing progress bar formatters because they all have the %curent% placeholder, so editing the placeholder's callback will be much more convenient.

I'm not seeking to create a progress bar with new customizations, it's just for a specific area of my codebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants