Giter Site home page Giter Site logo

xdebug-handler's Introduction

composer/xdebug-handler

packagist Continuous Integration license php

Restart a CLI process without loading the Xdebug extension, unless xdebug.mode=off.

Originally written as part of composer/composer, now extracted and made available as a stand-alone library.

Version 3

Removed support for legacy PHP versions and added type declarations.

Long term support for version 2 (PHP 5.3.2 - 7.2.4) follows Composer 2.2 LTS policy.

Installation

Install the latest version with:

$ composer require composer/xdebug-handler

Requirements

  • PHP 7.2.5 minimum, although using the latest PHP version is highly recommended.

Basic Usage

use Composer\XdebugHandler\XdebugHandler;

$xdebug = new XdebugHandler('myapp');
$xdebug->check();
unset($xdebug);

The constructor takes a single parameter, $envPrefix, which is upper-cased and prepended to default base values to create two distinct environment variables. The above example enables the use of:

  • MYAPP_ALLOW_XDEBUG=1 to override automatic restart and allow Xdebug
  • MYAPP_ORIGINAL_INIS to obtain ini file locations in a restarted process

Advanced Usage

How it works

A temporary ini file is created from the loaded (and scanned) ini files, with any references to the Xdebug extension commented out. Current ini settings are merged, so that most ini settings made on the command-line or by the application are included (see Limitations)

  • MYAPP_ALLOW_XDEBUG is set with internal data to flag and use in the restart.
  • The command-line and environment are configured for the restart.
  • The application is restarted in a new process.
    • The restart settings are stored in the environment.
    • MYAPP_ALLOW_XDEBUG is unset.
    • The application runs and exits.
  • The main process exits with the exit code from the restarted process.

See Examples for further information.

Signal handling

Asynchronous signal handling is automatically enabled if the pcntl extension is loaded. SIGINT is set to SIG_IGN in the parent process and restored to SIG_DFL in the restarted process (if no other handler has been set).

From PHP 7.4 on Windows, CTRL+C and CTRL+BREAK handling is automatically enabled in the restarted process and ignored in the parent process.

Limitations

There are a few things to be aware of when running inside a restarted process.

  • Extensions set on the command-line will not be loaded.
  • Ini file locations will be reported as per the restart - see getAllIniFiles().
  • Php sub-processes may be loaded with Xdebug enabled - see Process configuration.

Helper methods

These static methods provide information from the current process, regardless of whether it has been restarted or not.

getAllIniFiles(): array

Returns an array of the original ini file locations. Use this instead of calling php_ini_loaded_file and php_ini_scanned_files, which will report the wrong values in a restarted process.

use Composer\XdebugHandler\XdebugHandler;

$files = XdebugHandler::getAllIniFiles();

# $files[0] always exists, it could be an empty string
$loadedIni = array_shift($files);
$scannedInis = $files;

These locations are also available in the MYAPP_ORIGINAL_INIS environment variable. This is a path-separated string comprising the location returned from php_ini_loaded_file, which could be empty, followed by locations parsed from calling php_ini_scanned_files.

getRestartSettings(): ?array

Returns an array of settings that can be used with PHP sub-processes, or null if the process was not restarted.

use Composer\XdebugHandler\XdebugHandler;

$settings = XdebugHandler::getRestartSettings();
/**
 * $settings: array (if the current process was restarted,
 * or called with the settings from a previous restart), or null
 *
 *    'tmpIni'      => the temporary ini file used in the restart (string)
 *    'scannedInis' => if there were any scanned inis (bool)
 *    'scanDir'     => the original PHP_INI_SCAN_DIR value (false|string)
 *    'phprc'       => the original PHPRC value (false|string)
 *    'inis'        => the original inis from getAllIniFiles (array)
 *    'skipped'     => the skipped version from getSkippedVersion (string)
 */

getSkippedVersion(): string

Returns the Xdebug version string that was skipped by the restart, or an empty string if there was no restart (or Xdebug is still loaded, perhaps by an extending class restarting for a reason other than removing Xdebug).

use Composer\XdebugHandler\XdebugHandler;

$version = XdebugHandler::getSkippedVersion();
# $version: '3.1.1' (for example), or an empty string

isXdebugActive(): bool

Returns true if Xdebug is loaded and is running in an active mode (if it supports modes). Returns false if Xdebug is not loaded, or it is running with xdebug.mode=off.

Setter methods

These methods implement a fluent interface and must be called before the main check() method.

setLogger(LoggerInterface $logger): self

Enables the output of status messages to an external PSR3 logger. All messages are reported with either DEBUG or WARNING log levels. For example (showing the level and message):

// No restart
DEBUG    Checking MYAPP_ALLOW_XDEBUG
DEBUG    The Xdebug extension is loaded (3.1.1) xdebug.mode=off
DEBUG    No restart (APP_ALLOW_XDEBUG=0) Allowed by xdebug.mode

// Restart overridden
DEBUG    Checking MYAPP_ALLOW_XDEBUG
DEBUG    The Xdebug extension is loaded (3.1.1) xdebug.mode=coverage,debug,develop
DEBUG    No restart (MYAPP_ALLOW_XDEBUG=1)

// Failed restart
DEBUG    Checking MYAPP_ALLOW_XDEBUG
DEBUG    The Xdebug extension is loaded (3.1.0)
WARNING  No restart (Unable to create temp ini file at: ...)

Status messages can also be output with XDEBUG_HANDLER_DEBUG. See Troubleshooting.

setMainScript(string $script): self

Sets the location of the main script to run in the restart. This is only needed in more esoteric use-cases, or if the argv[0] location is inaccessible. The script name -- is supported for standard input.

setPersistent(): self

Configures the restart using persistent settings, so that Xdebug is not loaded in any sub-process.

Use this method if your application invokes one or more PHP sub-process and the Xdebug extension is not needed. This avoids the overhead of implementing specific sub-process strategies.

Alternatively, this method can be used to set up a default Xdebug-free environment which can be changed if a sub-process requires Xdebug, then restored afterwards:

function SubProcessWithXdebug()
{
    $phpConfig = new Composer\XdebugHandler\PhpConfig();

    # Set the environment to the original configuration
    $phpConfig->useOriginal();

    # run the process with Xdebug loaded
    ...

    # Restore Xdebug-free environment
    $phpConfig->usePersistent();
}

Process configuration

The library offers two strategies to invoke a new PHP process without loading Xdebug, using either standard or persistent settings. Note that this is only important if the application calls a PHP sub-process.

Standard settings

Uses command-line options to remove Xdebug from the new process only.

  • The -n option is added to the command-line. This tells PHP not to scan for additional inis.
  • The temporary ini is added to the command-line with the -c option.

If the new process calls a PHP sub-process, Xdebug will be loaded in that sub-process (unless it implements xdebug-handler, in which case there will be another restart).

This is the default strategy used in the restart.

Persistent settings

Uses environment variables to remove Xdebug from the new process and persist these settings to any sub-process.

  • PHP_INI_SCAN_DIR is set to an empty string. This tells PHP not to scan for additional inis.
  • PHPRC is set to the temporary ini.

If the new process calls a PHP sub-process, Xdebug will not be loaded in that sub-process.

This strategy can be used in the restart by calling setPersistent().

Sub-processes

The PhpConfig helper class makes it easy to invoke a PHP sub-process (with or without Xdebug loaded), regardless of whether there has been a restart.

Each of its methods returns an array of PHP options (to add to the command-line) and sets up the environment for the required strategy. The getRestartSettings() method is used internally.

  • useOriginal() - Xdebug will be loaded in the new process.
  • useStandard() - Xdebug will not be loaded in the new process - see standard settings.
  • userPersistent() - Xdebug will not be loaded in the new process - see persistent settings

If there was no restart, an empty options array is returned and the environment is not changed.

use Composer\XdebugHandler\PhpConfig;

$config = new PhpConfig;

$options = $config->useOriginal();
# $options:     empty array
# environment:  PHPRC and PHP_INI_SCAN_DIR set to original values

$options = $config->useStandard();
# $options:     [-n, -c, tmpIni]
# environment:  PHPRC and PHP_INI_SCAN_DIR set to original values

$options = $config->usePersistent();
# $options:     empty array
# environment:  PHPRC=tmpIni, PHP_INI_SCAN_DIR=''

Troubleshooting

The following environment settings can be used to troubleshoot unexpected behavior:

  • XDEBUG_HANDLER_DEBUG=1 Outputs status messages to STDERR, if it is defined, irrespective of any PSR3 logger. Each message is prefixed xdebug-handler[pid], where pid is the process identifier.

  • XDEBUG_HANDLER_DEBUG=2 As above, but additionally saves the temporary ini file and reports its location in a status message.

Extending the library

The API is defined by classes and their accessible elements that are not annotated as @internal. The main class has two protected methods that can be overridden to provide additional functionality:

requiresRestart(bool $default): bool

By default the process will restart if Xdebug is loaded and not running with xdebug.mode=off. Extending this method allows an application to decide, by returning a boolean (or equivalent) value. It is only called if MYAPP_ALLOW_XDEBUG is empty, so it will not be called in the restarted process (where this variable contains internal data), or if the restart has been overridden.

Note that the setMainScript() and setPersistent() setters can be used here, if required.

restart(array $command): void

An application can extend this to modify the temporary ini file, its location given in the tmpIni property. New settings can be safely appended to the end of the data, which is PHP_EOL terminated.

The $command parameter is an array of unescaped command-line arguments that will be used for the new process.

Remember to finish with parent::restart($command).

Example

This example demonstrates two ways to extend basic functionality:

  • To avoid the overhead of spinning up a new process, the restart is skipped if a simple help command is requested.

  • The application needs write-access to phar files, so it will force a restart if phar.readonly is set (regardless of whether Xdebug is loaded) and change this value in the temporary ini file.

use Composer\XdebugHandler\XdebugHandler;
use MyApp\Command;

class MyRestarter extends XdebugHandler
{
    private $required;

    protected function requiresRestart(bool $default): bool
    {
        if (Command::isHelp()) {
            # No need to disable Xdebug for this
            return false;
        }

        $this->required = (bool) ini_get('phar.readonly');
        return $this->required || $default;
    }

    protected function restart(array $command): void
    {
        if ($this->required) {
            # Add required ini setting to tmpIni
            $content = file_get_contents($this->tmpIni);
            $content .= 'phar.readonly=0'.PHP_EOL;
            file_put_contents($this->tmpIni, $content);
        }

        parent::restart($command);
    }
}

Examples

The tests\App directory contains command-line scripts that demonstrate the internal workings in a variety of scenarios. See Functional Test Scripts.

License

composer/xdebug-handler is licensed under the MIT License, see the LICENSE file for details.

xdebug-handler's People

Contributors

ajenbo avatar alcohol avatar carusogabriel avatar davidprevot avatar derrabus avatar felixfbecker avatar grahamcampbell avatar johnstevenson avatar keradus avatar kornrunner avatar ktomk avatar localheinz avatar pdelre avatar reedy avatar sanmai avatar seldaek avatar sidz avatar theofidry avatar tysonandre avatar weirdan avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xdebug-handler's Issues

Usage as a standalone binary

Would it be possible to implement a standalone binary based on the library that would run an arbitrary PHP application that doesn't have xdebug-handler bundled?

For instance, there's no plan to adapt it by PHPUnit (sebastianbergmann/phpunit#3544). Not having Xdebug loaded may significantly improve test performance, and code coverage may be collected by other means than Xdebug (e.g. PCOV).

Restarted (child) process does not return color output (automatically)

Following #86. I've created small reproducer repository for those issues:
https://github.com/k911/composer-xdebug-handler-signals-bug-reproducer

Composer\XdebugHandler does not detect properly (or at least automatically) TTY support in restarted process, which changes behaviour of CLI command.

Reproducer file colors.php

Requirements: xdebug and extension enabled

  1. At first run command without restarting process

    ➜ APP_ALLOW_XDEBUG=1 php colors.php

    Output:

    color-output

    Which is expected.

  2. Then, execute script without APP_ALLOW_XDEBUG environment variable

    ➜ php colors.php

    Output:

    no-color-output

I know, I still probably can force color output when using option like --ansi for some CLI tools, but in my opinion this should be detected automatically.

Proposed solution

Use for example symfony/process which can detect it in one line:
https://github.com/k911/swoole-bundle/blob/0dc13f00b5604cbae4e20147bdbce04e4d98eb9d/src/Common/XdebugHandler/XdebugHandler.php#L74

Fix color output handling

XdebugHandler only recognizes --ansi and --no-ansi command-line options, so we need to incorporate some of the other commonly used options:

--color, --colors, --color=..., --colors=...

I'll keep the changes small and simple.

Proposal: Disable Scan Directories Feature when restarting

I'am using php in a standard docker container FROM php:7.4-fpm which is compiled with --with-config-file-scan-dir

root@dev-6b74fdbbb-gwbnb:/var/www# php -i | grep scan
Configure Command => './configure' '--build=x86_64-linux-gnu' '--with-config-file-path=/usr/local/etc/php' '--with-config-file-scan-dir=/usr/local/etc/php/conf.d' '--enable-option-checking=fatal' '--with-mhash' '--with-pic' '--enable-ftp' '--enable-mbstring' '--enable-mysqlnd' '--with-password-argon2' '--with-sodium=shared' '--with-pdo-sqlite=/usr' '--with-sqlite3=/usr' '--with-curl' '--with-libedit' '--with-openssl' '--with-zlib' '--with-pear' '--with-libdir=lib/x86_64-linux-gnu' '--enable-fpm' '--with-fpm-user=www-data' '--with-fpm-group=www-data' '--disable-cgi' 'build_alias=x86_64-linux-gnu'

This leads to duplicate module loading when the temporary INI-File is generated from php_ini_scanned_files()

if ($scanned = php_ini_scanned_files()) {

I propose that the proc_open call should be provided with the PHP_INI_SCAN_DIR environment variable pointing to an directory containing an empty ini-file to resolve this issue:

$process = proc_open($cmd, array(), $pipes,null,['PHP_INI_SCAN_DIR' => '/tmp/test-scan-dir']);

$process = proc_open($cmd, array(), $pipes);

root@dev-6b74fdbbb-gwbnb:/var/www# ls /tmp/test-scan-dir/ -la
total 24
drwxr-xr-x 2 root root  4096 Oct 20 15:38 .
drwxrwxrwt 1 root root 20480 Oct 20 17:46 ..
-rw-r--r-- 1 root root     0 Oct 20 15:38 empty.ini
root@dev-6b74fdbbb-gwbnb:/var/www# cat /tmp/test-scan-dir/empty.ini 

Note the comment in the PHP Manual:
https://www.php.net/manual/en/configuration.file.php#configuration.file.scan

If a blank directory is given in PHP_INI_SCAN_DIR, PHP will also scan the directory given at compile time via --with-config-file-scan-dir.

Alternatively the temporary INI-File could be stored in a directory and included this why and not by using the -c-Flag:

array_push($php, '-n', '-c', $this->tmpIni);

I've encountered this issue in https://github.com/phpstan/phpstan.

Question of PHPRC

Why was it decided to use -c over PHPRC?

With the latter, the process is straightforward:

  • Create our our php.ini with all other files merged it.
  • Set PHPRC to point to a directory with our php.ini, set PHP_INI_SCAN_DIR to an empty string, with previous values saved somewhere.
  • Run the original command as it is in $argv in the updated environment.
  • Restore original PHPRC and PHP_INI_SCAN_DIR.

No need to twiddle with command line options. No need for any workarounds. All other php invocations will a vanilla environment transparently. Hence, this is also backward compatible.

Using our xdebug-free environment for any of sub-processes is as simple as setting our custom values for PHPRC and PHP_INI_SCAN_DIR. This can be done from a callback like below, so a user won't even need to know the details:

XdebugHandler::runWithoutXdebug(function () {
    $process = new Process();
    // and so on
});

getRestartSettings() and specifically getRestartSettings()['tmpIni'] will became redundant with this approach. All complexity will be hidden from a user.

(I've already changed Infection's xdebug-handler to follow roughly this approach, with success, and I think this project can be made to adopt it too. Surely not without an owner's approval.)

Merge all ini data to catch command-line ini settings

It is not possible to know if PHP is started with any -d ini value(s) so these will not be used for the restart.

As a workaround (to fix specific Composer issues) xdebug-handler adds memory_limit, disable_functions and allow_url_fopen to the temporary ini file. I PR-ed a way of including all ini settings but there was concern about the extra time this adds to the restart: composer/composer#6036

I have now set up a repo so that this can be tested on different set-ups: https://github.com/johnstevenson/xdebug-ini-test

Also included is a docker php image that uses a lot of ini files (58). Its test results can be seen here: https://travis-ci.org/johnstevenson/xdebug-ini-test

In my view, the more robust method of merging all ini data adds a negligible amount of time to the restart and is a fix-and-forget solution. Feedback appreciated. @Seldaek I would be interested to see if you still see the "3-400ms" lag and how this is split up (between ini creation and start-up times).

Cleanups now that proc_open is used

I wonder.. is Process::supportsColor and the whole colorOption concept still needed? I am guessing this was all workarounds because STDOUT wasn't bound properly in the child process. Not urgent by any means, but it might be good to clean things up.

Release process ?

Hi !
Is there any release process that users can be aware about?

We have bunch of good changes already merged to master, but not released:
1.1.0...master

Fun intersection with apc and Macs running Vagrant

When XDebug is turned on, and the XDebugHandler is initialised, on a Vagrant boxes with a CentOS installation, there's the following error when running Psalm:

PHP Fatal error:  PHP Startup: apc_mmap: mkstemp on /tmp/apc.KyxDdB failed: in Unknown on line 0

It's triggered when calling passthru.

This only happens when running Vagrant on macs, not on Linux.

I very much doubt this is the fault of XDebugHandler, but it obviously triggers the issue.

Possible performance issue with version 2.0.4

Hi :)

We're using FriendsOfPHP/PHP-CS-Fixer version 3.0.4 which relies on this package composer/xdebug-handler in version 2.

Since the recent upgrade from xdebug-handler version 2.0.3 to 2.0.4, PHP-CS-Fixer seems to be suffering from an important performance drop.

More details and procedure to reproduce the issue on the ticket I opened on their repository: PHP-CS-Fixer/PHP-CS-Fixer#6310

Support modern PHP for version 2

We could consider dropping support for older PHPs for version 2. Any dependents that support a PHP version less than whatever we decide our minimum is should be able to require ^1.4 || ^2.0, so their code will need to work with both versions.

Looking at all the dependents listed on Packagist, the vast majority do not extend the class so this is very simple (see item 1 below) and for those few that do extend the class it shouldn't really be any harder. The BC breaks will be:

  1. Constructor $colorOption optional param dropped:
    Using new XdebugHandler('myapp') would also work for 1.x because proc_open is used (unless only passthru is available). Using new XdebugHandler('myapp', '--ansi') would also work for 2.x since the extra param is ignored.

  2. Protected restart param $command changed from a string to an array:
    By not typehinting the method it can be used by 1.x and 2.x (unless $command is modified, which would require a little work - although this is not seen in any dependents).

  3. Protected requiresRestart param $isLoaded changed to $default:
    By not typehinting the method it can be used by 1.x and 2.x since both are boolean.

  4. The process will not restart if xdebug mode is off:
    This is not relevant to the code.

@Seldaek Interested in your input here. Perhaps a minimum of 7.1, although the xdebug mode stuff is only relevant on 7.2 upwards.

Xdebug 3 support

Xdebug 3 has an "off" switch so we can either set XDEBUG_MODE=off in env, or pass -dxdebug.mode=off to PHP when restarting. It should simplify things quite a bit as we don't need to rebuild the ini file and create a temp one etc.

This library does not work when invoking a Phar via a relative path

When the phar is invoked manually (e.g. php -d zend_extension=xdebug.so build/phan.phar), xdebug-handler fails to detect that the file exists.

Adding debugging statements, I see that the Phar path (i.e. $args[0]) gets replaced by '--' (EDIT: Because it fails to detect that the file exists, xdebug-handler attempts to pass the phar (I assume) over stdin, which doesn't work. That causes the phar to hang after the restart, with no output)

Patching getCommand() to use the following check would make it not replace the relative path with --: if (!file_exists($args[0]) && !file_exists(getcwd() . '/' . $args[0])) {

  • Obviously, you'd have to check if something is an absolute path, the above snippet is not what you'd really want to use. Something more like the below would make sense. I'm not sure if that's 100% correct -- You may wish to limit this to Phars only for now via https://secure.php.net/manual/en/phar.running.php (Feel free to use the below helper)
    public static function absScriptPath(string $relative_path)
    {   
        // Make sure its actually relative
        if (\DIRECTORY_SEPARATOR === \substr($relative_path, 0, 1)) {
            return $relative_path;
        }
        // Check for absolute path in windows, e.g. C:\ (https://en.wikipedia.org/wiki/Drive_letter_assignment)
        if (\DIRECTORY_SEPARATOR === "\\" &&
                \strlen($relative_path) > 3 &&
                \ctype_alpha($relative_path[0]) &&
                $relative_path[1] === ':' &&
                \strspn($relative_path, '/\\', 2, 1)) {
            return $relative_path;
        }

        return getcwd() . DIRECTORY_SEPARATOR . $relative_path;
    } 

https://stackoverflow.com/a/18378785 sounds like it describes the generic problem for Phars:

Working with file paths and Phar archives in PHP can be tricky. The PHP code inside of a Phar file will treat relative paths as being relative to the Phar archive, not relative to the current working directory.


My use case is building phars for https://github.com/phan/phan/releases

Robustness of the persistent option

When the persistent mode is used but PHP_INI_SCAN_DIR is ignored by the target binary, xdebug-handler will not notice that it didn't succeed. I am wondering if xdebug-handler should somehow detect that there was a problem.

See NixOS/nixpkgs#221845 for a case where that happened because of the specific way nix packages PHP.

Signals are not passed to the restarted (child) process

I've created small reproducer repository for this:
https://github.com/k911/composer-xdebug-handler-signals-bug-reproducer

Reproducer file: signals.php

Requirements: xdebug and pcntl PHP extensions enabled

  1. At first run command without restarting process, and after some time press CTRL-C combination (or send SIGINT signal, using kill -SIGINT PID)

    ➜ APP_ALLOW_XDEBUG=1 php signals.php
    
    # output:
    # 
    # Hello from PID: 11087
    # Started!
    # ^C
    # Stopping..
    # Stopped after 974 ms

    This is expected behaviour.

  2. Then, execute script without APP_ALLOW_XDEBUG environment variable

    ➜ php signals.php 
    
    # output:
    #
    # Hello from PID: 11677
    # Hello from PID: 11678
    # Started!
    # ^C

    As you can see, process was stopped, but signal handler were never executed, because CLI sends it to first process, not to the child. Of course, I could send signal to second (child) process, which will handle signal and end process, but it makes CLI commands being unfriendly for end users.

Proposed solution

Use for example symfony/process package, to create restarted process, and either pass all signals to child process or allow to customize it.

You can see POC solution here: https://github.com/k911/swoole-bundle/blob/0dc13f00b5604cbae4e20147bdbce04e4d98eb9d/src/Common/XdebugHandler/XdebugHandler.php#L79-L90

Blocking 1.0 release

It would be nice to have a list of what's blocking 1.0 release to contribute and have a rough ETA for adoption. Feel free to edit this issue or create milestone

How to replace colorOption in 2.0?

Hi,
I upgraded to version 2.0 and the 2nd constructor parameter vanished. I used to pass --ansi in there so that Symfony Console apps could continue to be in color.

What can I do in 2.0 to restore this behaviour? Thanks!

Unclear relevance for Composer

README contains:

Originally written as part of composer/composer, now extracted and made available as a stand-alone library.

My interpretation was that this code had been written in Composer, but that the Composer project then decided the code should be removed from Composer, so the code was made available in a new project. But my colleague Jonny Bradley points out that this issue seems to be solved in current Composer, so perhaps "extracted" should not be understood as "moved out" but as "copied".

Please make the README clear about whether the code is currently part of official Composer.

Save original xdebug settings

It would be great to store somewhere original xdebug parameters.

Q: Why do I need this?
A: Our application works on top of phpunit and we would like to know whether code coverage parameter was enabled after xdebug handler restarted process or not. Mostly it is needed for xdebug 3 and we would like to get at least xdebug.mode (for xdebug 3) and xdebug.coverage_enable (for xdebug < 3)

There is a workaround:
We may get and parse all ini files through XdebugHandler::getRestartSettings()['inis'] on our end but it would be good to have this feature in xdebug-handler.

I can spend some time and prepare a pull request if you think that it will be good to have such feature.

Unable to abort restarted process with Ctrl-C

Version 1.4.2 suppresses the SIGINT signal, and that suppression is inherited by the restarted process.

The reason for this explained in POSIX.1

Signals set to the default action (SIG_DFL) in the calling process image shall be set to the default action in the new process image. Except for SIGCHLD, signals set to be ignored (SIG_IGN) by the calling process image shall be set to be ignored by the new process image. Signals set to be caught by the calling process image shall be set to the default action in the new process image (see <signal.h>).

So, unless the application restores the signal handler or sets its own you cannot stop it with SIGINT anymore.

Originally posted by @weirdan in #108 (comment)

Reproduce repo
https://github.com/weirdan/xdebug-handler-unstoppable

Reproduce steps

  • git clone [email protected]:weirdan/xdebug-handler-unstoppable
  • cd xdebug-handler-unstoppable
  • composer install
  • php test.php
  • Press Ctrl-C

Expected result
The process should be aborted.

Actual result
The process is not aborted.

Additional details
Downgrading composer/xdebug-helper to 1.4.1 fixes the issue.

image

`ini_get` returning invalid values in some environments when php.ini is copied into tmp folder

I have an open issue on the PHPStan repo, which uses this library to detect if xdebug is running or not.

That issue probably explains it better than I can summarize here, but the tl/dr is that they're calling ini_get on post_max_size and it's returning '' in my environment. It appears to be happening when the php.ini is copied into a /tmp folder. If I call ini_get on post_max_size from the "normal" location, it returns the accurate value.

I'm not sure the next steps, but would love to get any eyes on it and happy to debug further!

INI file and broken disable_functions

I have an issue, when the copied ini file have proc_open in disable_functions, because of broken merging of additional files. This causes composer to stop working.

This is simplified reproduction of this issue:

php.ini - default from compilation

disable_functions=proc_open

And additional ini files

01-first.ini - this contains some rules in [PATH=..] section

[PATH=/var/www/html]
memory_limit=512G

02-second.ini - this contains rules without sections

disable_functions=""

Composer from these files will produce following ini file:

disable_functions=proc_open
[PATH=/var/www/html]
memory_limit=512G
disable_functions=""

As you can see disable_functions="" is no longer applicable to all scripts but only to /var/www/html. In addition to this also all composer settings are ignored as well, since these are in PATH section.

Escaping of arguments strips-out non-ASCII characters.

Description is copied from cakephp/debug_kit#637

DebugKit somehow corrupts base paths of programs run by composer when xdebug is installed on Linux.

Create a project directory, containg unicode characters in it's path, e.g.: /home/example/Пример/test/.
Create there following files: composer.json, and build.xml

composer.json

{
    "name": "test/example",
    "description": "",
    "homepage": "http://example.com",
    "type": "project",
    "license": "MIT",
    "require": {
        "cakephp/debug_kit": "^3.15.0",
        "phing/phing": "^2.16"
    },
    "scripts": {
        "build": "phing"
    }
}

build.xml

<?xml version="1.0" encoding="UTF-8"?>

<project default="build" basedir="." phingVersion="2.16.0">
    <!-- main tasks -->
    <target name="build">
        <exec executable="composer" checkreturn="true" logoutput="true">
            <arg value="validate"/>
            <arg value="--no-check-lock"/>
            <arg value="--no-interaction"/>
        </exec>
    </target>
</project>

Run composer run build. It will fail because of a corrupt path.

> phing
Buildfile: /home/example/Пример/test/build.xml

build.xml > build:

     [exec] Could not open input file: /home/example//test/vendor/bin/composer

BUILD FAILED

Expected

> phing
Buildfile: /home/example/Пример/test/build.xml

build.xml > build:

     [exec] ./composer.json is valid

BUILD FINISHED

Total time: 0.2745 seconds

Remove cakephp/debug_kit from composer.json, run composer update and then run composer run build. The build command will finish successfully.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.