Skip to content

psysh appears to (c)lose mysqli connection #677

Closed

Description

@MonsieurCellophane

Greetings.
Using psysh v10.8 (great job BTW) to break in a moodle module I am developing. It appears that this causes the mysqli connection to go away in a semi-random fashion (meaning moving breaks around results in different outcomes).
The diagnostic is:

Couldn't fetch mysqli in [...]/lib/dml/mysqli_native_moodle_database.php

This error is always present at exit, but it does also appear during program execution depending on the breakpoint(s) location (and just before errors, $DB->mysqli->ping() returns indeed false).

I use ^D to get out of a breakpoint and continue execution, and I am speculating that the destructor for the global $DB object is called when i do that (the destructor calls mysqli->close()).

Is that what I am seeing, and if so, can it be avoided?

Activity

  1. MonsieurCellophane commented on Jul 2, 2021

    @MonsieurCellophane
    Author

    I put together a minimal CLI script illustrating the issue.
    This (given correct credentials: replace username and password in the code) runs to the end if invoked as php cli.php while bombing on the second and third ->ping() (and ->close) if invoked as php cli.php -d. This with either mysqli.reconnect=Off or On in php.ini

    <?php
    $options=getopt("dv",["debug","verbose"],$rst_index);
    $me=$argv[0];
    if(is_array($options)) {
        $i=0;
        while($i<$rst_index){array_shift($argv);$i++;}
        $DBG=array_key_exists('d',$options) || array_key_exists('debug',$options);
        $VERBOSE=array_key_exists('v',$options) || array_key_exists('verbose',$options);
    } else {
        error_log("Error in parsing CLI arguments:",join(',',$argv));
        die("Aborted\n");
    }
    if($DBG) {
        try {
            require('vendor/autoload.php');
        } catch (Exception $e) {
            error_log("In require: " . $e->getMessage() . "\n");
        }
    }
    $PSYSH=function_exists('psy\debug'); 
    $conn=new mysqli('localhost','root','x'); // OK
    $conn->ping();                            // OK
    if ($PSYSH) { eval(\Psy\Sh()); }
    $conn->ping();                            // FAILS with -d
    if ($PSYSH) { eval(\Psy\Sh()); }
    echo $conn->ping();                       //FAILS with -d
    $conn->close();
    
    
  2. MonsieurCellophane commented on Jul 2, 2021

    @MonsieurCellophane
    Author

    Also:

    # php -v
    PHP 7.3.27 (cli) (built: Feb  2 2021 10:32:50) ( NTS )
    Copyright (c) 1997-2018 The PHP Group
    Zend Engine v3.3.27, Copyright (c) 1998-2018 Zend Technologies
        with Zend OPcache v7.3.27, Copyright (c) 1999-2018, by Zend Technologies
    
  3. bobthecow commented on Jul 2, 2021

    @bobthecow
    Owner

    Try disabling forking ('usePcntl' => false in psysh config ).

  4. bobthecow commented on Jul 3, 2021

    @bobthecow
    Owner

    Yep, confirmed with your repro script. It seems like mysqli doesn't play nice with forking. It's probably that one of the other threads automatically cleaned up the connection while the main thread wasn't looking?

    I've also confirmed that disabling pcntl via the psysh config fixes your issue.

  5. MonsieurCellophane commented on Jul 5, 2021

    @MonsieurCellophane
    Author

    That's it. I can make the same happen, with no psysh in the loop, by opening a connection, forking, using it in children processes and exiting. After the first child terminates, the connection becomes useless for evey other process in the group (parent or child). I get "Mysql has gone away", not "couldn't fetch mysqli" but I think the root cause is the same. Mysql documentation mentions terminating connections on client exit, which could be the cause. I searched to see if signals are involved and, if so, ways to trap them before mysql gets wind of them, but no luck.

  6. bobthecow commented on Feb 21, 2022

    @bobthecow
    Owner

    Updated the Troubleshooting page of the wiki. I'm not sure what else we can do with it from our end, especially since the error happens after the shell exits? ¯_(ツ)_/¯

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions