JRL
JRL

Reputation: 850

Getting a Segmentation Fault on executing a query with a PDO instance

When using a PDO instance to execute a query, the script produces a segmentation fault. This occurs after verifying that the PDO object is indeed an instance of the PDO class:

var_dump($db)

Which resulted in:

Object(PDO)#16 {
}

It would also successfully execute a query without a segmentation fault immediately after instantiating the object, but not later in the script.

Upvotes: 2

Views: 1153

Answers (1)

JRL
JRL

Reputation: 850

The problem ended up being a quirk of PHP's objects, and a developer that was trying to be too clever.

In PHP, objects are passed by reference (sort of) into all scopes. This means that a child scope can alter the object in the parent scope. To avoid this, the program I was working in stored the objects in a value store, and this value store would CLONE the variable before returning it if it was an object:

    public function getConfig(string $key)
    {
        if ($this->hasConfig($key) === true) {
            if (is_object($this->configValues[$key]) === true) {
                return clone $this->configValues[$key];
            } else {
                return $this->configValues[$key];
            }
        } else {
            return null;
        }
    }

The clone keyword (detailed here) creates a shallow copy of the object and its properties, while maintaining all properties that are references.

When a PDO object is cloned however, it does not maintain the stream handler that allows it to connect to the database, however it does maintain the reference.

Unfortunately, this causes a segmentation fault.

I suspect this is because internally either memory out of range (protected) is being accessed, or because the library which actually allows PHP to talk to MySQL/databases with PDO doesn't allow the stream handler to be passed in this way.

Regardless of the causes, if you clone a PDO object and then use it to query, it will cause a segmentation fault that doesn't produce errors or exceptions allowing you to debug the problem.

The actual database object must always be passed and used.

I've created this question and answer to record this particular quirk, as I wasn't able to find any reference to this particular behavior on Google when I was originally trying to debug the issue.

This behavior was observed in PHP 7.2.16, and I have not verified if it will produce similar behavior in other versions of PHP.

The expected behavior, if the stream handler cannot be safely cloned in this way, is for the clone keyword to throw an exception when used on a PDO object.

EDIT:

Another factor which may contribute (again, this isn't something I tested extensively) is that this particular connection uses the PDO::MYSQL_ATTR_SSL_CA attribute to set an SSL cert .pem file.

Upvotes: 2

Related Questions