php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #53716 segfault in $stmt->execute()
Submitted: 2011-01-12 07:27 UTC Modified: 2013-01-08 12:18 UTC
Votes:3
Avg. Score:4.3 ± 0.5
Reproduced:3 of 3 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: anthon dot pang at gmail dot com Assigned: johannes
Status: Duplicate Package: PDO related
PHP Version: 5.3.5 OS: Ubuntu 10.04
Private report: No CVE-ID:
 [2011-01-12 07:27 UTC] anthon dot pang at gmail dot com
Description:
------------
The snippet of code shown used is a method from a class that subclasses Zend_Db_Adapter_Abstract. We make a lot of query() calls, so caching prepared statements reportedly gives us a 10% performance improvement.

#! /bin/sh
#
# Created by configure

'./configure' \
'--with-mysqli=mysqlnd' \
'--with-pdo-mysql=mysqlnd' \
'--with-zlib' \
'--enable-zip' \
'--with-gd' \
'--with-curl' \
'--enable-mbstring' \
'--enable-debug' \
"$@"



Test script:
---------------
	public function query($sql, $bind = array())
	{
		static $cachePreparedStatement = array();
	
		if(isset($cachePreparedStatement[$sql]))
		{
			if (!is_array($bind)) {
				$bind = array($bind);
			}
			$stmt = $cachePreparedStatement[$sql];
			$stmt->execute($bind);
			return $stmt;
		}

		$stmt = parent::query($sql, $bind);
		$cachePreparedStatement[$sql] = $stmt;
		return $stmt;
	}


Expected result:
----------------
No crash.

Actual result:
--------------
Program received signal SIGSEGV, Segmentation fault.
0x003c7816 in ?? () from /lib/tls/i686/cmov/libc.so.6
(gdb) bt
#0  0x003c7816 in ?? () from /lib/tls/i686/cmov/libc.so.6
#1  0x082818c6 in do_fetch (stmt=0x99cb938, do_bind=1, return_value=0x8f5c78c, 
    how=PDO_FETCH_ASSOC, ori=PDO_FETCH_ORI_NEXT, offset=0, return_all=0x0)
    at /home/apang/work/php/php-5.3.5/ext/pdo/pdo_stmt.c:1044
#2  0x082825a2 in zim_PDOStatement_fetch (ht=3, return_value=0x8f5c78c, 
    return_value_ptr=0x0, this_ptr=0xb7ecba54, return_value_used=1)
    at /home/apang/work/php/php-5.3.5/ext/pdo/pdo_stmt.c:1316
#3  0x08501e58 in zend_do_fcall_common_helper_SPEC (execute_data=0x8bd0dc0)
    at /home/apang/work/php/php-5.3.5/Zend/zend_vm_execute.h:316
#4  0x08502415 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x8bd0dc0)
    at /home/apang/work/php/php-5.3.5/Zend/zend_vm_execute.h:421
#5  0x085014f5 in execute (op_array=0x971d190)
    at /home/apang/work/php/php-5.3.5/Zend/zend_vm_execute.h:107
#6  0x084c6e07 in zend_call_function (fci=0xbfffce28, fci_cache=0xbfffce4c)
    at /home/apang/work/php/php-5.3.5/Zend/zend_execute_API.c:964
#7  0x083849e1 in zif_call_user_func_array (ht=2, return_value=0x9a03db0, 
    return_value_ptr=0x0, this_ptr=0x0, return_value_used=0)
    at /home/apang/work/php/php-5.3.5/ext/standard/basic_functions.c:4796
#8  0x08501e58 in zend_do_fcall_common_helper_SPEC (execute_data=0x8bcffdc)
    at /home/apang/work/php/php-5.3.5/Zend/zend_vm_execute.h:316
#9  0x08505918 in ZEND_DO_FCALL_SPEC_CONST_HANDLER (execute_data=0x8bcffdc)
    at /home/apang/work/php/php-5.3.5/Zend/zend_vm_execute.h:1606
#10 0x085014f5 in execute (op_array=0x8e7bd1c)
---Type <return> to continue, or q <return> to quit---
    at /home/apang/work/php/php-5.3.5/Zend/zend_vm_execute.h:107
#11 0x084d488e in zend_execute_scripts (type=8, retval=0x0, file_count=3)
    at /home/apang/work/php/php-5.3.5/Zend/zend.c:1194
#12 0x0846a4ee in php_execute_script (primary_file=0xbffff2e4)
    at /home/apang/work/php/php-5.3.5/main/main.c:2265
#13 0x08592c71 in main (argc=2, argv=0xbffff474)
    at /home/apang/work/php/php-5.3.5/sapi/cli/php_cli.c:1193




Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-01-12 12:00 UTC] pajoye@php.net
-Status: Open +Status: Feedback
 [2011-01-12 12:00 UTC] pajoye@php.net
Thank you for this bug report. To properly diagnose the problem, we
need a short but complete example script to be able to reproduce
this bug ourselves. 

A proper reproducing script starts with <?php and ends with ?>,
is max. 10-20 lines long and does not require any external 
resources such as databases, etc. If the script requires a 
database to demonstrate the issue, please make sure it creates 
all necessary tables, stored procedures etc.

Please avoid embedding huge scripts into the report.


 [2011-01-12 17:24 UTC] anthon dot pang at gmail dot com
-Status: Feedback +Status: Open
 [2011-01-12 17:24 UTC] anthon dot pang at gmail dot com
I'm in the middle of a project.  For reference, the segfault occurs in r3717:

http://dev.piwik.org/trac/changeset/3717/trunk?old_path=%2F&format=zip

Please keep this ticket open until I have some free time to troubleshoot and isolate a smaller test case.  (I can already tell you it'll require database access and be more than the arbitrary 20 line limit.)

Additional info:

Same code doesn't crash when using MYSQLI or php 5.2.17.  (Tested/segfaulted with 5.3.2, 5.3.3, 5.3.4, and 5.3.5.  These are all vanilla builds using source downloads from php.net.)
 [2011-02-09 05:15 UTC] max at axismedia dot ru
Looks like I have very similar problem. In short php 5.3 in CLI or Apach module 
mode, PDO compiled againt mysqlnd crashes when using MySQL native prepared 
queries with segmentation fault.

EXAMPLE SCRIPT

<?php

$driver_options = array(PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,.
                        PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8';",
                        PDO::ATTR_PERSISTENT         => true,
                        PDO::MYSQL_ATTR_DIRECT_QUERY => false);

$sql = 'SELECT NOW()';

$pdo = new PDO('mysql:host=localhost;dbname=m_shop', 'max', null, 
$driver_options);
$st = $pdo->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
print "before execute\n";
$st->execute();
print "after execute\n";
$st->closeCursor();

$pdo = null;

?>

Output:

office tmp # php bug.php
before execute
after execute
Segmentation fault (core dumped)

BACKTRACE

(gdb) bt
#0  0xb6acb02d in free () from /lib/libc.so.6
#1  0x082f8208 in _mysqlnd_pefree (ptr=0x0, persistent=1 '\001', tsrm_ls=0x0) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_debug.c:1062
#2  0x082e97c8 in php_mysqlnd_stmt_free_result_bind_pub (s=0x8b56024, 
result_bind=0x8b24a60, tsrm_ls=0x891e280)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_ps.c:2296
#3  0x082e9856 in mysqlnd_stmt_separate_result_bind (s=0x8b56024, tsrm_ls=<value 
optimized out>)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_ps.c:2029
#4  0x082e98d3 in php_mysqlnd_stmt_free_result_pub (s=0x8b56024, 
tsrm_ls=0x891e280) at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_ps.c:1961
#5  0x081e8e11 in pdo_mysql_stmt_cursor_closer (stmt=0x8b24240, 
tsrm_ls=0x891e280) at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/pdo_mysql/mysql_statement.c:906
#6  0x081e4471 in zim_PDOStatement_closeCursor (ht=0, return_value=0x8b24154, 
return_value_ptr=0x0, this_ptr=0x8b24170, return_value_used=0, 
tsrm_ls=0x891e280)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/pdo/pdo_stmt.c:2141
#7  0x0839edf1 in zend_do_fcall_common_helper_SPEC (execute_data=0x8b56058, 
tsrm_ls=0x891e280)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/Zend/zend_vm_execute.h:316
#8  0x0839f2f1 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER (execute_data=0x1, 
tsrm_ls=0x8b24a54) at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/Zend/zend_vm_execute.h:421
#9  0x083786a6 in execute (op_array=0x8b23124, tsrm_ls=0x891e280) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/Zend/zend_vm_execute.h:107
#10 0x08353317 in zend_execute_scripts (type=8, tsrm_ls=0x891e280, retval=0x0, 
file_count=3) at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/Zend/zend.c:1194
#11 0x082fcee9 in php_execute_script (primary_file=0xbfbfa920, 
tsrm_ls=0x891e280) at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/main/main.c:2265
#12 0x083d6fe6 in main (argc=2, argv=0xbfbfaa24) at /var/tmp/portage/dev-
lang/php-5.3.5/work/sapis-build/cli/sapi/cli/php_cli.c:1193

NOTES

1. If i do not call $st->closeCursor() i still get segmentation fault but with a 
bit different backtrace (same problem but on php environment shutdown):

#0  0xffffe424 in __kernel_vsyscall ()
#1  0xb6a4c401 in raise () from /lib/libc.so.6
#2  0xb6a4db42 in abort () from /lib/libc.so.6
#3  0xb6a87815 in ?? () from /lib/libc.so.6
#4  0xb6a8d6d1 in ?? () from /lib/libc.so.6
#5  0xb6a8ef38 in ?? () from /lib/libc.so.6
#6  0xb6a9203d in free () from /lib/libc.so.6
#7  0x082f8208 in _mysqlnd_pefree (ptr=0x0, persistent=48 '0', tsrm_ls=0x400) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_debug.c:1062
#8  0x082e97c8 in php_mysqlnd_stmt_free_result_bind_pub (s=0x8b56024, 
result_bind=0x8b24a4c, tsrm_ls=0x891e280)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_ps.c:2296
#9  0x082e9856 in mysqlnd_stmt_separate_result_bind (s=0x8b56024, tsrm_ls=<value 
optimized out>)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_ps.c:2029
#10 0x082e99a3 in php_mysqlnd_stmt_free_stmt_content_pub (s=0x8b56024, 
tsrm_ls=0x891e280) at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_ps.c:2125
#11 0x082eb441 in php_mysqlnd_stmt_net_close_priv (s=0x8b56024, implicit=0 
'\000', tsrm_ls=0x891e280)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_ps.c:2212
#12 0x082eaf9e in php_mysqlnd_stmt_dtor_pub (s=0x8b56024, implicit=6 '\006', 
tsrm_ls=0x891e280)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/mysqlnd/mysqlnd_ps.c:2239
#13 0x081e9d89 in pdo_mysql_stmt_dtor (stmt=0x8b24560, tsrm_ls=0x891e280) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/pdo_mysql/mysql_statement.c:64
#14 0x081e357c in free_statement (stmt=0x8b24560, tsrm_ls=<value optimized out>) 
at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/ext/pdo/pdo_stmt.c:2398
#15 0x081e36d8 in php_pdo_stmt_delref (stmt=0x0, tsrm_ls=0x891e280) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-build/cli/ext/pdo/pdo_stmt.c:2440
#16 0x081e36f2 in pdo_dbstmt_free_storage (stmt=0x8b24560, tsrm_ls=0x891e280) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-build/cli/ext/pdo/pdo_stmt.c:2446
#17 0x08374b9b in zend_objects_store_del_ref_by_handle_ex (handle=2, 
handlers=0x891c180, tsrm_ls=0x891e280)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/Zend/zend_objects_API.c:220
#18 0x08374cab in zend_objects_store_del_ref (zobject=0x8b240d8, 
tsrm_ls=0x891e280) at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/Zend/zend_objects_API.c:172
#19 0x0835303e in _zval_dtor_func (zvalue=0x8b240d8) at /var/tmp/portage/dev-
lang/php-5.3.5/work/sapis-build/cli/Zend/zend_variables.c:52
#20 0x083483f9 in _zval_dtor (zval_ptr=0x8b244bc) at /var/tmp/portage/dev-
lang/php-5.3.5/work/sapis-build/cli/Zend/zend_variables.h:35
#21 _zval_ptr_dtor (zval_ptr=0x8b244bc) at /var/tmp/portage/dev-lang/php-
5.3.5/work/sapis-build/cli/Zend/zend_execute_API.c:443
#22 0x0835f42c in zend_hash_apply_deleter (ht=0x89204f0, p=0x8b244b0) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-build/cli/Zend/zend_hash.c:614
#23 0x0835f4d8 in zend_hash_reverse_apply (ht=0x89204f0, apply_func=0x8347a56 
<zval_call_destructor>, tsrm_ls=0x891e280)
    at /var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/Zend/zend_hash.c:763
#24 0x08348c79 in shutdown_destructors (tsrm_ls=0x891e280) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-
build/cli/Zend/zend_execute_API.c:226
#25 0x08353dd2 in zend_call_destructors (tsrm_ls=0x891e280) at 
/var/tmp/portage/dev-lang/php-5.3.5/work/sapis-build/cli/Zend/zend.c:874
#26 0x082fd893 in php_request_shutdown (dummy=0x0) at /var/tmp/portage/dev-
lang/php-5.3.5/work/sapis-build/cli/main/main.c:1587
#27 0x083d782b in main (argc=2, argv=0xbfbc8ae4) at /var/tmp/portage/dev-
lang/php-5.3.5/work/sapis-build/cli/sapi/cli/php_cli.c:1374

2. If i use emulated prepares (PDO::MYSQL_ATTR_DIRECT_QUERY => true) everyting 
is fine.

3. If compile PDO against standard mysqlclientlib driver everything is fine.

4. Situation is reproduced at x86 and x86_64
 [2011-02-09 05:27 UTC] max at axismedia dot ru
In update to my previous message:

5. If i switch persistent connection off (PDO::ATTR_PERSISTENT => false) 
everithing is fine too.
 [2011-06-13 03:33 UTC] felipe@php.net
-Status: Open +Status: Feedback
 [2011-06-13 03:33 UTC] felipe@php.net
Please try using this snapshot:

  http://snaps.php.net/php5.3-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/


 [2012-01-18 16:51 UTC] silvio dot ginter at volz-itsc dot de
+1 for me....

This problem still exists in PHP 5.3.9 under OpenSUSE 11.4. All packages were 
taken from OpenSUSE Yast Repositories.


Output of Apache HTTP Daemon:
-----------------------------
[Wed Jan 18 16:45:06 2012] [notice] Apache/2.2.21 (Linux/SUSE) mod_ssl/2.2.21 
OpenSSL/1.0.0c PHP/5.3.9 configured -- resuming normal operations
*** glibc detected *** /usr/sbin/httpd2-prefork: free(): invalid pointer: 
0x00007f1902d75608 ***


Output of php -i | grep mysql
-----------------------------
/etc/php5/conf.d/mysql.ini,
/etc/php5/conf.d/mysqli.ini,
/etc/php5/conf.d/mysqlnd.ini,
/etc/php5/conf.d/pdo_mysql.ini,
mysql
Client API version => mysqlnd 5.0.8-dev - 20102224 - $Revision: 321634 $
mysql.allow_local_infile => On => On
mysql.allow_persistent => On => On
mysql.connect_timeout => 60 => 60
mysql.default_host => no value => no value
mysql.default_password => no value => no value
mysql.default_port => no value => no value
mysql.default_socket => /var/lib/mysql/mysql.sock => /var/lib/mysql/mysql.sock
mysql.default_user => no value => no value
mysql.max_links => Unlimited => Unlimited
mysql.max_persistent => Unlimited => Unlimited
mysql.trace_mode => Off => Off
mysqli
Client API library version => mysqlnd 5.0.8-dev - 20102224 - $Revision: 321634 $
mysqli.allow_local_infile => On => On
mysqli.allow_persistent => On => On
mysqli.default_host => no value => no value
mysqli.default_port => 3306 => 3306
mysqli.default_pw => no value => no value
mysqli.default_socket => /var/lib/mysql/mysql.sock => /var/lib/mysql/mysql.sock
mysqli.default_user => no value => no value
mysqli.max_links => Unlimited => Unlimited
mysqli.max_persistent => Unlimited => Unlimited
mysqli.reconnect => Off => Off
mysqlnd
mysqlnd => enabled
Version => mysqlnd 5.0.8-dev - 20102224 - $Revision: 321634 $
Tracing => d:t:x:O,/tmp/mysqlnd.trace
PDO drivers => mysql, odbc, pgsql, sqlite, sqlite2
pdo_mysql
Client API version => mysqlnd 5.0.8-dev - 20102224 - $Revision: 321634 $
pdo_mysql.default_socket => /var/lib/mysql/mysql.sock => 
/var/lib/mysql/mysql.sock
 [2013-01-08 03:14 UTC] avejidah at hotmail dot com
I see that it's been a year since anyone posted here.  This problem still exists 
in Ubuntu 12.04, fully updated 

mysqlnd 5.0.8-dev

PHP 5.3.10-1ubuntu3.4 with Suhosin-Patch (cli) (built: Sep 12 2012 19:00:43) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
    with Xdebug v2.1.0, Copyright (c) 2002-2010, by Derick Rethans

--------
  $conStr   = 'mysql:host=localhost;port=3306;dbname=MASKED;charset=utf8';
  $username = 'MASKED';
  $password = 'MASKED';
  $userID   = 3;

  $pdo = new PDO($conStr, $username, $password,
    array
    (   
      PDO::ATTR_PERSISTENT       => true,
      PDO::ATTR_ERRMODE          => PDO::ERRMODE_EXCEPTION,
      PDO::ATTR_EMULATE_PREPARES => false // Change to true = no crash.
    )); 

    $stmt = $pdo->prepare
    ("  
      SELECT *
      FROM   Users u
      WHERE  userID = :userID
    ");

    $stmt->bindValue(':userID', $userID);
    echo "Bound...";
    if ($stmt->execute())
    {
      echo 'Success';
    }   
    else
      throw new Exception('Failed to exec.');

----
 [2013-01-08 03:50 UTC] rasmus@php.net
Johannes, could you take a look. We are freeing an invalid pointer here somehow. 
I was able to replicate it. It is on the free of a bound param.

ext/pdo_mysql/mysql_statement.c does:

    if (S->stmt) {
        pdo_mysql_stmt_close(S->stmt);
        S->stmt = NULL;
    }

which hits mysqlnd_stmt::dtor() in ext/mysqlnd/mysqlnd_ps.c
which in turn calls mysqlnd_stmt::net_close() which does:

   s->m->free_stmt_content(s TSRMLS_CC);

which, of course, hits mysqlnd_stmt::free_stmt_content() which calls:

   s->m->free_parameter_bind(s, stmt->param_bind TSRMLS_CC);

which calls _mysqlnd_pefree() and we get the crash on the pefree() there in 
mysqlnd_alloc.c

Interestingly enough there is no crash when run using USE_ZEND_ALLOC=0
 [2013-01-08 03:50 UTC] rasmus@php.net
-Assigned To: +Assigned To: johannes
 [2013-01-08 11:16 UTC] johannes@php.net
-Status: Feedback +Status: Closed
 [2013-01-08 11:16 UTC] johannes@php.net
Thank you for your bug report. This issue has already been fixed
in the latest released version of PHP, which you can download at 
http://www.php.net/downloads.php

This seems to be fixed as of 5.3.14 and 5.4.4.
 [2013-01-08 12:18 UTC] johannes@php.net
-Status: Closed +Status: Duplicate
 [2013-01-08 12:18 UTC] johannes@php.net
Same as (fixed) bug #61411
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Sun Apr 20 15:01:54 2014 UTC