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 (profile)
Status: Duplicate Package: PDO related
PHP Version: 5.3.5 OS: Ubuntu 10.04
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: anthon dot pang at gmail dot com
New email:
PHP Version: OS:

 

 [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

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-2024 The PHP Group
All rights reserved.
Last updated: Sat Sep 07 23:01:27 2024 UTC