php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #61411 PDO Segfaults with PERSISTENT == TRUE && EMULATE_PREPARES == FALSE
Submitted: 2012-03-16 09:16 UTC Modified: 2020-12-09 15:47 UTC
Votes:21
Avg. Score:4.8 ± 0.5
Reproduced:14 of 16 (87.5%)
Same Version:5 (35.7%)
Same OS:5 (35.7%)
From: julien at palard dot fr Assigned: nikic (profile)
Status: Closed Package: PDO MySQL
PHP Version: 5.4.0 OS: Linux 2.6.32-5-amd64
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: julien at palard dot fr
New email:
PHP Version: OS:

 

 [2012-03-16 09:16 UTC] julien at palard dot fr
Description:
------------
PDO Segfaults or hangs when a statement is executed with both ATTR_PERSISTENT => 
TRUE and ATTR_EMULATE_PREPARES => FALSE

The exact bug is actually :
*** glibc detected *** /usr/local/php-5.4.0/bin/php: free(): invalid pointer: 
0x00007ff976ee84c8 ***
But from my tests yesterday I have seen a segfault and a double free, that I 
can't reproduce today, only the invalid pointer.

Playing with PERSISTENT and EMULATE_PREPARE with the given test script give :

| ATTR_PERSISENT | ATTR_EMULATE_PREPARES |                  WORKS |
|          FALSE |                 FALSE |                    YES |
|          FALSE |                  TRUE |                    YES |
|           TRUE |                 FALSE | free() invalid pointer |
|           TRUE |                  TRUE |                    YES |

Configure command : 

./configure'  '--enable-fpm' '--prefix=/usr/local/php-5.4.0' '--enable-mbstring' 
'--enable-gd-native-ttf' '--enable-zip' '--with-mcrypt' '--with-openssl' '--
with-gd' '--with-jpeg-dir=/usr/lib' '--with-freetype-dir' '--with-curl' '--with-
pcre-regex' '--with-gettext' '--without-sqlite' '--without-sqlite3' '--with-pdo-
mysql=mysqlnd' '--disable-rpath' '--disable-debug' '--disable-fileinfo' '--
without-pdo-sqlite' '--disable-phar' '--disable-posix' '--disable-tokenizer' '--
disable-xmlreader' '--disable-xmlwriter' '--without-pear'

Same bug reproduced in php 5.3.8 and php 5.3.10

Test script:
---------------
<?php

$options = array(PDO::ATTR_PERSISTENT => TRUE,
                 PDO::ATTR_EMULATE_PREPARES => FALSE); 

$pdo = new PDO('mysql:host=sql;dbname=??;charset=utf8',
               '??', '??', $options);

$statement = $pdo->prepare("SELECT count(*) from a_table");
$statement->execute();
foreach ($statement as $line)
    var_dump($line);


Expected result:
----------------
I expect PHP not to segfault

Actual result:
--------------
*** glibc detected *** /usr/local/php-5.4.0/bin/php: free(): invalid pointer: 
0x00007ff976ee84c8 ***


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-05-02 09:14 UTC] uw@php.net
Andrey,

do you think we should mnd_p*alloc(.., .., stmt->persistent) here?



http://svn.php.net/viewvc/php/php-src/branches/PHP_5_4/ext/mysqlnd/mysqlnd_ps.c?annotate=321634

1624 	  	  	if (!stmt->result_bind) {
1625 	andrey 	289028 	stmt->result_bind = mnd_ecalloc(stmt->field_count, sizeof(MYSQLND_RESULT_BIND));
1626 	andrey 	258383 	} else {
1627 	andrey 	289028 	stmt->result_bind = mnd_erealloc(stmt->result_bind, stmt->field_count * sizeof(MYSQLND_RESULT_BIND));
1628 	andrey 	258383 	}
 [2012-05-04 08:56 UTC] uw@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.

http://news.php.net/php.cvs/68917
 [2012-05-04 08:56 UTC] uw@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: uw
 [2013-01-08 17:48 UTC] rasmus@php.net
I can still reproduce this in PHP 5.4.12-dev built today.
 [2013-01-08 17:48 UTC] rasmus@php.net
-Status: Closed +Status: Re-Opened
 [2013-01-18 01:07 UTC] don at smugmug dot com
I can reproduce this in 5.4.10 and 5.4.4, FWIW.
 [2013-01-18 03:59 UTC] don at smugmug dot com
FWIW, 5.3.3 segfaults like this, but 5.3.2 doesn't.  I spot-checked a handful of 
other versions up to .21 and they all segfaulted as well.
 [2013-08-12 11:08 UTC] mike@php.net
Can any of you still reproduce this?
 [2014-01-01 12:40 UTC] felipe@php.net
-Package: PDO related +Package: PDO MySQL
 [2014-12-23 11:24 UTC] fundom02 at yahoo dot com
Hi,

I'm using PHP 5.6.3 and I still see this bug.

Darren
 [2014-12-23 23:00 UTC] don at smugmug dot com
I just tried the given test script against PHP-5.6.4 and it didn't segfault for me. 

I'll try our main codebase on it and see if it's been resolved.
 [2014-12-26 11:43 UTC] fundom02 at yahoo dot com
Perhaps this is a slightly different problem with the same symptoms.

The problem I see is using ATTR_PERSISTENT => true with ATTR_EMULATE_PREPARES => false with a low wait_timeout on the server causes "MySQL server has gone away" issues. 

To replicate this try the following.

Configure your MySQL with a wait_timeout of 2 seconds.

Then run the following. 
                                                

	    function create_connection(){
		$options = array(PDO::ATTR_PERSISTENT => TRUE,PDO::ATTR_EMULATE_PREPARES => FALSE); 
		return new PDO('mysql:host=127.0.0.1;dbname=trafficadbar;charset=utf8',
		    'root', 'wnn99BCc', $options);
	    }


	    $pdo = create_connection();
	    sleep(5);
	    $pdo1 = create_connection();

	    $statement = $pdo1->prepare("SELECT count(*) from users");
	    $statement->execute();
	    foreach ($statement as $line)
		var_dump($line);
 [2014-12-26 18:45 UTC] don at smugmug dot com
Ahhh... That doesn't sound like a bug, actually.  The connection is properly timing out on the MySQL side because enough seconds have passed.  Just reconnect and continue on?
 [2014-12-26 18:52 UTC] Fundom02 at yahoo dot com
This is a bug.

$pdo creates a new connection. 2 seconds later MySQL closes that connection. 3 seconds later $pdo1 requests a completely new connection which is instantly reported as lost connection.

I believe that php-pdo is caching all connections and not checking if cached connections are closed.

If this weren't the case then $pdo1 would successfully create a new connection.
 [2015-01-13 11:31 UTC] fundom02 at yahoo dot com
Any news on this?
 [2015-01-14 18:17 UTC] mike@php.net
Are you experiencing a crash?
 [2015-01-14 18:24 UTC] Fundom02 at yahoo dot com
I get an error, caused by php returning a cached connection that's expired.

If you run my code you will see the problem.
 [2015-01-14 22:05 UTC] don at smugmug dot com
We've been running with PERSISTENT = TRUE && EMULATE_PREPARES = FALSE on our testbed since December 23rd, with no segfaults or any other problems with connections, including the ones described by Fundom02.  We'll likely push this change to production shortly.
 [2015-01-15 10:38 UTC] fundom02 at yahoo dot com
Don,

That's interesting. Have you tried my code with settings your MySQL timeout less than than the sleep?

function create_connection(){
		$options = array(PDO::ATTR_PERSISTENT => TRUE,PDO::ATTR_EMULATE_PREPARES => FALSE); 
		return new PDO('mysql:host=127.0.0.1;dbname=trafficadbar;charset=utf8',
		    'root', 'wnn99BCc', $options);
	    }


	    $pdo = create_connection();
	    sleep(5);
	    $pdo1 = create_connection();

	    $statement = $pdo1->prepare("SELECT count(*) from users");
	    $statement->execute();
	    foreach ($statement as $line)
		var_dump($line);
 [2015-06-25 15:19 UTC] nachms+php at gmail dot com
I ran all the various tests here, and could not recreate any issues. I've even forcefully restarted MySQL in the middle of a script running to see what would happen, and things went fine.

I'm using:
PHP 5.6.9-1 (cli) (built: May 22 2015 10:48:57)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies
    with XCache v3.2.0, Copyright (c) 2005-2014, by mOo
    with Suhosin v0.9.37.1, Copyright (c) 2007-2014, by SektionEins GmbH
    with XCache Optimizer v3.2.0, Copyright (c) 2005-2014, by mOo
    with XCache Cacher v3.2.0, Copyright (c) 2005-2014, by mOo
    with XCache Coverager v3.2.0, Copyright (c) 2005-2014, by mOo

With the mysqlnd extension and mysql Ver 14.14 Distrib 5.5.43, for debian-linux-gnu (x86_64) using readline 6.3.

Aside from the original reporter, no one specified which MySQL extension they were using, so it's possible certain bugs exist in certain versions with a certain extension, but it's unclear which exactly.
 [2017-07-14 15:30 UTC] ashokcsenitj16 at gmail dot com
Hi All,

I am getting following error 

SQLSTATE[HY000]: General error: 1615 Prepared statement needs to be re-prepared

with PDO::ATTR_PERSISTENT => TRUE, PDO::ATTR_EMULATE_PREPARES => FALSE

Can anyone please help me in this?
 [2017-07-24 06:36 UTC] julien at palard dot fr
ashokcsenitj16 at gmail dot com: Your issue is not linked to this issue, you're not having a segfault, please ask elsewhere or open a new one if you think it's a bug.
 [2017-10-24 04:10 UTC] kalle@php.net
-Assigned To: uw +Assigned To:
 [2020-12-09 15:47 UTC] nikic@php.net
-Status: Re-Opened +Status: Closed -Assigned To: +Assigned To: nikic
 [2020-12-09 15:47 UTC] nikic@php.net
As far as I can tell, the segfault issue has been resolved, and any other problems that may exist should be reported separately.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 01:01:30 2024 UTC