|   | php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | 
| 
  [2010-04-27 04:57 UTC] ww dot galen at gmail dot com
 Description:
------------
After executing a prepared statement and calling PDOStatement::nextRowset (whether 
or not there is more than one result set), then calling PDOStatement::execute a 
second time, PDOStatement::getColumnMeta causes a segfault. I guess it really is 
an experimental feature. 
  Platform info:
OS X 10.6.3
Apache 2.2.14
PHP 5.3.2 (also tested under 5.3.1 with same result)
MySQL 5.1.45
Test script:
---------------
$db = new PDO('mysql:...', ...);
$query = $db->prepare('SELECT 1 AS num;');
$query->execute();
$query->nextRowset();
$query->execute();
$query->getColumnMeta(0);
Expected result:
----------------
PDOStatement::getColumnMeta should return an array describing a column. For the 
test script, something like:
<code>
  array (
    'native_type' => 'LONGLONG',
    'pdo_type' => 2,
    'flags' => 
    array (
      0 => 'not_null',
    ),
    'table' => '',
    'name' => 'num',
    'len' => 1,
    'precision' => 0,
  )
</code>
Actual result:
--------------
Segfault. For example, on my machine I get:
Process:         httpd [31734]
Path:            /usr/sbin/httpd
Identifier:      httpd
Version:         ??? (???)
Code Type:       X86-64 (Native)
Parent Process:  httpd [31718]
Date/Time:       2010-04-26 19:02:55.650 -0700
OS Version:      Mac OS X 10.6.3 (10D573)
Report Version:  6
Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000000
Crashed Thread:  0  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   libphp5.so                    	0x0000000101163923 
zim_PDOStatement_getColumnMeta + 262
1   libphp5.so                    	0x0000000101334704 
zend_do_fcall_common_helper_SPEC + 2409
2   libphp5.so                    	0x0000000101330fd9 execute + 585
3   libphp5.so                    	0x000000010130fe18 zend_execute_scripts 
+ 376
4   libphp5.so                    	0x00000001012c2b3a php_execute_script + 
705
5   libphp5.so                    	0x000000010138baf3 php_handler + 1237
6   httpd                         	0x00000001000012af ap_run_handler + 90
7   httpd                         	0x0000000100001b8e ap_invoke_handler + 
346
8   httpd                         	0x000000010002e784 ap_process_request + 
103
9   httpd                         	0x000000010002aff7 
ap_process_http_connection + 116
10  httpd                         	0x000000010001280b 
ap_run_process_connection + 90
11  httpd                         	0x0000000100012ca5 ap_process_connection 
+ 91
12  httpd                         	0x00000001000353f2 child_main + 1257
13  httpd                         	0x00000001000355a8 make_child + 329
14  httpd                         	0x000000010003582e 
perform_idle_server_maintenance + 498
15  httpd                         	0x0000000100035d58 ap_mpm_run + 1246
16  httpd                         	0x00000001000098f5 main + 2854
17  httpd                         	0x0000000100000914 start + 52
Thread 0 crashed with X86 Thread State (64-bit):
  rax: 0x0000000000000001  rbx: 0x0000000000000000  rcx: 0x00007fff5fbfef48  
rdx: 0x0000000000000028
  rdi: 0x00000001007412be  rsi: 0x00000001013dbdde  rbp: 0x00007fff5fbfeff0  
rsp: 0x00007fff5fbfefc0
   r8: 0x0000000000000001   r9: 0x0000000000000006  r10: 0x00000001013cf158  
r11: 0x00000001007412b8
  r12: 0x000000010073d000  r13: 0x000000010073c4a0  r14: 0x0000000000000001  
r15: 0x0000000000000000
  rip: 0x0000000101163923  rfl: 0x0000000000000246  cr2: 0x0000000000000000
Patchesfix-nextRowset.getColumnMeta-segfault (last revision 2010-04-27 03:35 UTC by ww dot galen at gmail dot com)Pull RequestsHistoryAllCommentsChangesGit/SVN commits             | |||||||||||||||||||||||||||
|  Copyright © 2001-2025 The PHP Group All rights reserved. | Last updated: Fri Oct 31 01:00:01 2025 UTC | 
In particular, it's failing on line 1864 of pdo_stmt.c: add_assoc_string(return_value, "name", col->name, 1); 'col' is null because 'stmt->columns' is null.The cause seems to be lines 513-523 of pdo_stmt.c: if (!stmt->executed) { /* this is the first execute */ if (stmt->dbh->alloc_own_columns && !stmt->columns) { /* for "big boy" drivers, we need to allocate memory to fetch * the results into, so lets do that now */ ret = pdo_stmt_describe_columns(stmt TSRMLS_CC); } stmt->executed = 1; } Columns are only described if the statement hasn't been executed.Moving the inner test to just after the outer test so that columns are described whenever "stmt->columns" is null seems to fix the segfault. This is what the patch does, reproduced here: if (!stmt->executed) { /* this is the first execute */ stmt->executed = 1; } // if nextRowset was called, we need to redescribe if (stmt->dbh->alloc_own_columns && !stmt->columns) { /* for "big boy" drivers, we need to allocate memory to fetch * the results into, so lets do that now */ ret = pdo_stmt_describe_columns(stmt TSRMLS_CC); } Whether this is appropriate and won't cause other bugs or even if it fixes all cases, I couldn't tell you.