Edit report at http://bugs.php.net/bug.php?id=53551&edit=1

 ID:                 53551
 Updated by:         u...@php.net
 Reported by:        eddawley at gmail dot com
 Summary:            PDOStatement execute segfaults for pdo_mysql driver
 Status:             Assigned
 Type:               Bug
 Package:            PDO related
 Operating System:   Centos 5
 PHP Version:        5.3.4
 Assigned To:        mysql
 Block user comment: N
 Private report:     N

 New Comment:

That fix should do it, however, I'd like to wait until Johannes returns
from vacation and reviews it. PDO is a bit of a beast. With the fix the
code should neither crash nor leak, nor behave differently from
PDO_SQlite. Anyway, the result is still pretty, well, PDOish weird:
error codes not cleaned up properly upon rebinding. Not my cup of
coffee...



Index: ext/pdo_mysql/mysql_statement.c                                  
       

===================================================================     
       

--- ext/pdo_mysql/mysql_statement.c     (Revision 307155)               
       

+++ ext/pdo_mysql/mysql_statement.c     (Arbeitskopie)    

@@ -141,10 +141,12 @@                                                   
       

                                                                        
       

        /* (re)bind the parameters */                                   
       

        if (mysql_stmt_bind_param(S->stmt, S->params) ||
mysql_stmt_execute(S->stmt)) {

+               /*                                                      
              

                if (S->params) {                                        
              

                        efree(S->params);                               
              

                        S->params = 0;                                  
              

                }                                                       
              

+               */                                                      
              

                pdo_mysql_error_stmt(stmt);                             
              

                if (mysql_stmt_errno(S->stmt) == 2057) {                
              

                        /* CR_NEW_STMT_METADATA makes the statement
unusable */


Previous Comments:
------------------------------------------------------------------------
[2010-12-17 20:58:27] eddawley at gmail dot com

Sorry, I didn't realize I was being unclear.  The segfault is occurring
with PDO 

using libmysql.



Here are my relevant configure options:



'--with-mysql=mysqlnd' '--with-mysqli' '--with-pdo-mysql'

------------------------------------------------------------------------
[2010-12-17 20:44:00] ka...@php.net

MySQLnd is not a driver, its a library backend. MySQL, MySQLi and
PDO_MySQL can all be powered by either libmysql or mysqlnd.



So what you are saying is that you built pdo_mysql against libmysql
which segfaults?

------------------------------------------------------------------------
[2010-12-17 19:38:02] eddawley at gmail dot com

I would like to add that this happens for other mysql-level errors.  For


example, the following will also cause a segfault when reused:



SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or
update a 

child 

row: a foreign key constraint fails ...



SQLSTATE[22003]: Numeric value out of range: 1264 Out of range value for


column...



And again, this was noticed with the pdo_mysql driver.  NOT the mysqlnd
native 

driver.

------------------------------------------------------------------------
[2010-12-16 22:58:35] ka...@php.net

I cannot reproduce with php-trunk using pdo_mysql linked to mysqlnd on
Windows:



C:\php>php test.php

1

array(3) {

  [0]=>

  string(5) "00000"

  [1]=>

  NULL

  [2]=>

  NULL

}

2

array(3) {

  [0]=>

  string(5) "00000"

  [1]=>

  NULL

  [2]=>

  NULL

}



done



C:\php>php -v

PHP 5.3.99-dev (cli) (built: Dec 11 2010 12:14:13)

Copyright (c) 1997-2010 The PHP Group

Zend Engine v2.4.0, Copyright (c) 1998-2010 Zend Technologies

------------------------------------------------------------------------
[2010-12-15 22:31:18] eddawley at gmail dot com

Description:
------------
A segfault will occur when a PDOStatement is reused after failing due to
a NOT 

NULL integrity constraint.  This occurred when using the pdo_mysql
driver as 

opposed to the mysqlnd driver.



Also to avoid confusion, I was only able to test this on PHP 5.3.2.  I
could find 

nothing in the changelogs that would imply this bug has been fixed.  I 

unfortunately did not have the time to free up hardware or vms for an
upgrade.

Test script:
---------------
$dbh = new PDO('mysql:host=127.0.0.1;dbname=foo', 'user', 'pass');

$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);



$createSql = "CREATE TABLE `foo` (

  `count` bigint(20) unsigned NOT NULL DEFAULT '0'

)";



$dbh->exec('drop table if exists foo');

$dbh->exec($createSql);

$dbh->exec("insert into foo set `count` = 1 ");



$sql = 'UPDATE foo SET `count` = :count';

$stmt = $dbh->prepare($sql);



$values = array (

  'count' => NULL,

);



echo "1\n";

$stmt->execute($values);

var_dump($stmt->errorInfo());



echo "2\n";

$stmt->execute($values);

var_dump($stmt->errorInfo());



echo "\ndone\n";



Expected result:
----------------
[...@foo ~]$ php ed.php

1

array(3) {

  [0]=>

  string(5) "23000"

  [1]=>

  int(1048)

  [2]=>

  string(29) "Column 'count' cannot be null"

}

2

array(3) {

  [0]=>

  string(5) "23000"

  [1]=>

  int(1048)

  [2]=>

  string(29) "Column 'count' cannot be null"

}

done



Actual result:
--------------
[...@foo ~]$ php ed.php

1

array(3) {

  [0]=>

  string(5) "23000"

  [1]=>

  int(1048)

  [2]=>

  string(29) "Column 'count' cannot be null"

}

2

Segmentation fault (core dumped)







Core was generated by `php ed.php'.

Program terminated with signal 11, Segmentation fault.

[New process 16072]

#0  0x00000000005aa8be in pdo_mysql_stmt_param_hook (stmt=0xe5c12e8, 

param=0xe5c1a78, event_type=<value optimized out>) at /tmp/php-

5.3.2/ext/pdo_mysql/mysql_statement.c:490

490                                     b->is_null = &S->in_null[param-

>paramno];

(gdb) bt

#0  0x00000000005aa8be in pdo_mysql_stmt_param_hook (stmt=0xe5c12e8, 

param=0xe5c1a78, event_type=<value optimized out>) at /tmp/php-

5.3.2/ext/pdo_mysql/mysql_statement.c:490

#1  0x00000000005a34d9 in really_register_bound_param
(param=0x7ffff7cb9990, 

stmt=0xe5c12e8, is_param=1) at /tmp/php-5.3.2/ext/pdo/pdo_stmt.c:408

#2  0x00000000005a4940 in zim_PDOStatement_execute (ht=<value optimized
out>, 

return_value=0xe5c18d0, return_value_ptr=<value optimized out>,
this_ptr=<value 

optimized out>, 

    return_value_used=<value optimized out>) at /tmp/php-

5.3.2/ext/pdo/pdo_stmt.c:474

#3  0x0000000000789059 in zend_do_fcall_common_helper_SPEC 

(execute_data=0x2ae09210b050) at
/tmp/php-5.3.2/Zend/zend_vm_execute.h:313

#4  0x000000000075f98e in execute (op_array=0xe5be920) at /tmp/php-

5.3.2/Zend/zend_vm_execute.h:104

#5  0x000000000073c439 in zend_execute_scripts (type=8, retval=0x0, 

file_count=3) at /tmp/php-5.3.2/Zend/zend.c:1194

#6  0x00000000006ea968 in php_execute_script
(primary_file=0x7ffff7cbc190) at 

/tmp/php-5.3.2/main/main.c:2260

#7  0x00000000007c617e in main (argc=2, argv=0x7ffff7cbc408) at
/tmp/php-

5.3.2/sapi/cli/php_cli.c:1192

(gdb) print *param

$1 = {paramno = 0, name = 0xe5c0750 ":count", namelen = 6, max_value_len
= 0, 

parameter = 0xe5c1900, param_type = PDO_PARAM_STR, driver_params = 0x0,


driver_data = 0x0, 

  stmt = 0xe5c12e8, is_param = 1}

(gdb) print param

$2 = (struct pdo_bound_param_data *) 0xe5c1a78




------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=53551&edit=1

Reply via email to