php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #49098 Using custom session handler causes segfault in session_save_state
Submitted: 2009-07-29 12:12 UTC Modified: 2010-11-10 21:34 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:1 (50.0%)
From: bugs at timj dot co dot uk Assigned: timj (profile)
Status: Closed Package: Session related
PHP Version: 5.2.10 OS: Linux
Private report: No CVE-ID: None
 [2009-07-29 12:12 UTC] bugs at timj dot co dot uk
Description:
------------
I am seeing segfaults on various pages that don't occur on 5.2.9 (and the same site has been working on many previous versions of 5.1/5.2). I have a session handler using PEAR HTTP_Session2, that saves via MDB2/mysqli to a MySQL database. The segfaults seem to happen during session_save_state.

Unfortunately I don't currently have a trivial reproduction scenario, but it does reliably cause a segfault in both 5.2.10 and 5.2SVN-snap200907182030.

I am not a C developer but after a diligent attempt to search the bugtracker and investigate the bug, I concluded that it was probably duplicate of bug #48922 and tried to add additional information to that bug, explaining my reasoning, to avoid filing a duplicate (in accordance with http://bugs.php.net/report.php). However, Jani disagrees (see comments in other bug), so I'm filing a new bug.

Actual result:
--------------
Here's 5.2.10: (crash in version_compare):

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff1ea4d3f in _zend_mm_free_int (heap=0x7ffff8396480,
p=0x7ffff8bb7010) at /usr/src/debug/php-5.2.10/Zend/zend_alloc.c:1978
1978		if (ZEND_MM_IS_FREE_BLOCK(next_block)) {
(gdb) bt
#0  0x00007ffff1ea4d3f in _zend_mm_free_int (heap=0x7ffff8396480,
p=0x7ffff8bb7010) at /usr/src/debug/php-5.2.10/Zend/zend_alloc.c:1978
#1  0x00007ffff1ea5af4 in _efree (ptr=0x7ffff8bb7010) at
/usr/src/debug/php-5.2.10/Zend/zend_alloc.c:2311
#2  0x00007ffff1e3f4ff in php_version_compare (orig_ver1=0x7ffff87b7538
"5.2.10", orig_ver2=0x7ffff8e41ac0 "5.0") at
/usr/src/debug/php-5.2.10/ext/standard/versioning.c:202
#3  0x00007ffff1e3f58b in zif_version_compare (ht=3,
return_value=0x7ffff87bc458, return_value_ptr=0x0, this_ptr=0x0,
return_value_used=1) at
/usr/src/debug/php-5.2.10/ext/standard/versioning.c:222
#4  0x00007ffff1ef028d in zend_do_fcall_common_helper_SPEC
(execute_data=0x7fffffffac00) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:200
#5  0x00007ffff1ef4235 in ZEND_DO_FCALL_SPEC_CONST_HANDLER
(execute_data=0x7fffffffac00) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:1739
#6  0x00007ffff1eefd6f in execute (op_array=0x7ffff8a028c0) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:92
#7  0x00007ffff1ef043e in zend_do_fcall_common_helper_SPEC
(execute_data=0x7fffffffba00) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:234
#8  0x00007ffff1ef0984 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER
(execute_data=0x7fffffffba00) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:322
#9  0x00007ffff1eefd6f in execute (op_array=0x7ffff8b696e8) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:92
#10 0x00007ffff1ef043e in zend_do_fcall_common_helper_SPEC
(execute_data=0x7fffffffbf60) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:234
#11 0x00007ffff1ef0984 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER
(execute_data=0x7fffffffbf60) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:322
#12 0x00007ffff1eefd6f in execute (op_array=0x7ffff8b69588) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:92
#13 0x00007ffff1ef043e in zend_do_fcall_common_helper_SPEC
(execute_data=0x7fffffffc2d0) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:234
#14 0x00007ffff1ef0984 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER
(execute_data=0x7fffffffc2d0) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:322
#15 0x00007ffff1eefd6f in execute (op_array=0x7ffff8b6a728) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:92
#16 0x00007ffff1ef043e in zend_do_fcall_common_helper_SPEC
(execute_data=0x7fffffffd1c0) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:234
#17 0x00007ffff1ef0984 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER
(execute_data=0x7fffffffd1c0) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:322
#18 0x00007ffff1eefd6f in execute (op_array=0x7ffff8e29300) at
/usr/src/debug/php-5.2.10/Zend/zend_vm_execute.h:92
#19 0x00007ffff1eb816b in zend_call_function (fci=0x7fffffffd440,
fci_cache=0x0) at
/usr/src/debug/php-5.2.10/Zend/zend_execute_API.c:1032
#20 0x00007ffff1eb66d4 in call_user_function_ex
(function_table=0x7ffff8396d20, object_pp=0x0,
function_name=0x7ffff8e3eea0, retval_ptr_ptr=0x7fffffffd4e8,
param_count=2, params=0x7ffff87b7670, no_separation=1, 
    symbol_table=0x0) at
/usr/src/debug/php-5.2.10/Zend/zend_execute_API.c:640
#21 0x00007ffff1eb65af in call_user_function
(function_table=0x7ffff8396d20, object_pp=0x0,
function_name=0x7ffff8e3eea0, retval_ptr=0x7ffff87b7c18, param_count=2,
params=0x7fffffffd590)
    at /usr/src/debug/php-5.2.10/Zend/zend_execute_API.c:613
#22 0x00007ffff1da4785 in ps_call_handler (func=0x7ffff8e3eea0, argc=2,
argv=0x7fffffffd590) at
/usr/src/debug/php-5.2.10/ext/session/mod_user.c:53
#23 0x00007ffff1da4c2d in ps_write_user (mod_data=0x7ffff221db60,
key=0x7ffff8e3f7c0 "59ufo7hqslet38p73jp9na8577", 
    val=0x7ffff8fb1e88
"__HTTP_Session2_Info|i:2;__HTTP_Session2_Idle|i:3600;__HTTP_Session2_Id
le_TS|i:1247951369;user_id|s:1:\"6\";audit_user|N;", vallen=119) at
/usr/src/debug/php-5.2.10/ext/session/mod_user.c:141
#24 0x00007ffff1d9d8ba in php_session_save_current_state () at
/usr/src/debug/php-5.2.10/ext/session/session.c:556
#25 0x00007ffff1da0fbb in php_session_flush () at
/usr/src/debug/php-5.2.10/ext/session/session.c:1408
#26 0x00007ffff1da31cc in zm_deactivate_session (type=1,
module_number=17) at
/usr/src/debug/php-5.2.10/ext/session/session.c:2010
#27 0x00007ffff1ecd24b in module_registry_cleanup
(module=0x7ffff83c8550) at
/usr/src/debug/php-5.2.10/Zend/zend_API.c:1976
#28 0x00007ffff1ed2ba7 in zend_hash_reverse_apply (ht=0x7ffff2221e20,
apply_func=0x7ffff1ecd20c <module_registry_cleanup>) at
/usr/src/debug/php-5.2.10/Zend/zend_hash.c:755
#29 0x00007ffff1ec5628 in zend_deactivate_modules () at
/usr/src/debug/php-5.2.10/Zend/zend.c:838
#30 0x00007ffff1e6de29 in php_request_shutdown (dummy=0x0) at
/usr/src/debug/php-5.2.10/main/main.c:1468
#31 0x00007ffff1f475f9 in php_apache_request_dtor (r=0x7ffff87edb38) at
/usr/src/debug/php-5.2.10/sapi/apache2handler/sapi_apache2.c:472
#32 0x00007ffff1f47e6a in php_handler (r=0x7ffff87edb38) at
/usr/src/debug/php-5.2.10/sapi/apache2handler/sapi_apache2.c:644
#33 0x00007ffff7fd9600 in ap_run_handler (r=0x7ffff87edb38) at
/usr/src/debug/httpd-2.2.11/server/config.c:158
#34 0x00007ffff7fdce98 in ap_invoke_handler (r=0x7ffff87edb38) at
/usr/src/debug/httpd-2.2.11/server/config.c:372
#35 0x00007ffff7fe852e in ap_process_request (r=0x7ffff87edb38) at
/usr/src/debug/httpd-2.2.11/modules/http/http_request.c:282
#36 0x00007ffff7fe5328 in ap_process_http_connection (c=0x7ffff87e7cf8)
at /usr/src/debug/httpd-2.2.11/modules/http/http_core.c:190
#37 0x00007ffff7fe1048 in ap_run_process_connection (c=0x7ffff87e7cf8)
at /usr/src/debug/httpd-2.2.11/server/connection.c:43
#38 0x00007ffff7fecf78 in child_main (child_num_arg=<value optimized
out>) at /usr/src/debug/httpd-2.2.11/server/mpm/prefork/prefork.c:650
#39 0x00007ffff7fed1f6 in make_child (s=0x7ffff8212f90, slot=0) at
/usr/src/debug/httpd-2.2.11/server/mpm/prefork/prefork.c:690
#40 0x00007ffff7fed853 in ap_mpm_run (_pconf=<value optimized out>,
plog=<value optimized out>, s=<value optimized out>) at
/usr/src/debug/httpd-2.2.11/server/mpm/prefork/prefork.c:966
#41 0x00007ffff7fc56d0 in main (argc=14, argv=0x7fffffffe128) at
/usr/src/debug/httpd-2.2.11/server/main.c:740
(gdb) frame 2
#2  0x00007ffff1e3f4ff in php_version_compare (orig_ver1=0x7ffff87b7538
"5.2.10", orig_ver2=0x7ffff8e41ac0 "5.0") at
/usr/src/debug/php-5.2.10/ext/standard/versioning.c:202
202		efree(ver1);

The above call appears to have come via "version_compare(phpversion(),
"5.0", ">="))" in MDB2::classExists().

However, running exactly the same page with the 5.2 snapshot from
200907182030 results in apparently the same behaviour (segfault) but in
a completely different function:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff1ea373a in _zend_mm_alloc_int (heap=0x7ffff83964a0, size=12)
at /usr/src/debug/php5.2-200907182030/Zend/zend_alloc.c:1785
1785				heap->cache[index] = best_fit->prev_free_block;
(gdb) bt
#0  0x00007ffff1ea373a in _zend_mm_alloc_int (heap=0x7ffff83964a0,
size=12) at /usr/src/debug/php5.2-200907182030/Zend/zend_alloc.c:1785
#1  0x00007ffff1ea4bbc in _emalloc (size=12) at
/usr/src/debug/php5.2-200907182030/Zend/zend_alloc.c:2300
#2  0x00007ffff1ea4d49 in _safe_emalloc (nmemb=3, size=4, offset=0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_alloc.c:2391
#3  0x00007ffff1d3d24c in php_pcre_match_impl (pce=0x7ffff8bd8360,
subject=0x7ffff8b998a8
"__HTTP_Session2_Info|i:2;__HTTP_Session2_Idle|i:3600;__HTTP_Session2_Id
le_TS|i:1247953764;user_id|s:1:\"6\";audit_user|N;", 
    subject_len=119, return_value=0x7ffff87b99f0, subpats=0x0, global=0,
use_flags=0, flags=0, start_offset=0) at
/usr/src/debug/php5.2-200907182030/ext/pcre/php_pcre.c:603
#4  0x00007ffff1d3cfe8 in php_do_pcre_match (ht=2,
return_value=0x7ffff87b99f0, return_value_ptr=0x0, this_ptr=0x0,
return_value_used=1, global=0) at
/usr/src/debug/php5.2-200907182030/ext/pcre/php_pcre.c:513
#5  0x00007ffff1d3db55 in zif_preg_match (ht=2,
return_value=0x7ffff87b99f0, return_value_ptr=0x0, this_ptr=0x0,
return_value_used=1) at
/usr/src/debug/php5.2-200907182030/ext/pcre/php_pcre.c:762
#6  0x00007ffff1eef409 in zend_do_fcall_common_helper_SPEC
(execute_data=0x7fffffffbfe0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:200
#7  0x00007ffff1ef33b1 in ZEND_DO_FCALL_SPEC_CONST_HANDLER
(execute_data=0x7fffffffbfe0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:1739
#8  0x00007ffff1eeeeeb in execute (op_array=0x7ffff8ec85a0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:92
#9  0x00007ffff1eef5ba in zend_do_fcall_common_helper_SPEC
(execute_data=0x7fffffffc2d0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:234
#10 0x00007ffff1eefb00 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER
(execute_data=0x7fffffffc2d0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:322
#11 0x00007ffff1eeeeeb in execute (op_array=0x7ffff8b69d80) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:92
#12 0x00007ffff1eef5ba in zend_do_fcall_common_helper_SPEC
(execute_data=0x7fffffffd1c0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:234
#13 0x00007ffff1eefb00 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER
(execute_data=0x7fffffffd1c0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:322
#14 0x00007ffff1eeeeeb in execute (op_array=0x7ffff8e29508) at
/usr/src/debug/php5.2-200907182030/Zend/zend_vm_execute.h:92
#15 0x00007ffff1eb727b in zend_call_function (fci=0x7fffffffd440,
fci_cache=0x0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_execute_API.c:1032
#16 0x00007ffff1eb57e4 in call_user_function_ex
(function_table=0x7ffff8396d40, object_pp=0x0,
function_name=0x7ffff8e3f1f0, retval_ptr_ptr=0x7fffffffd4e8,
param_count=2, params=0x7ffff87b7850, no_separation=1, 
    symbol_table=0x0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_execute_API.c:640
#17 0x00007ffff1eb56bf in call_user_function
(function_table=0x7ffff8396d40, object_pp=0x0,
function_name=0x7ffff8e3f1f0, retval_ptr=0x7ffff87b75f0, param_count=2,
params=0x7fffffffd590)
    at /usr/src/debug/php5.2-200907182030/Zend/zend_execute_API.c:613
#18 0x00007ffff1da385d in ps_call_handler (func=0x7ffff8e3f1f0, argc=2,
argv=0x7fffffffd590) at
/usr/src/debug/php5.2-200907182030/ext/session/mod_user.c:53
#19 0x00007ffff1da3d05 in ps_write_user (mod_data=0x7ffff221db20,
key=0x7ffff8d8e290 "l41av5sk36mub26qvgm1t61672", 
    val=0x7ffff8fb2470
"__HTTP_Session2_Info|i:2;__HTTP_Session2_Idle|i:3600;__HTTP_Session2_Id
le_TS|i:1247953764;user_id|s:1:\"6\";audit_user|N;", vallen=119) at
/usr/src/debug/php5.2-200907182030/ext/session/mod_user.c:141
#20 0x00007ffff1d9c98a in php_session_save_current_state () at
/usr/src/debug/php5.2-200907182030/ext/session/session.c:556
#21 0x00007ffff1da008b in php_session_flush () at
/usr/src/debug/php5.2-200907182030/ext/session/session.c:1408
#22 0x00007ffff1da229c in zm_deactivate_session (type=1,
module_number=17) at
/usr/src/debug/php5.2-200907182030/ext/session/session.c:2010
#23 0x00007ffff1ecc35b in module_registry_cleanup
(module=0x7ffff83c86f0) at
/usr/src/debug/php5.2-200907182030/Zend/zend_API.c:1976
#24 0x00007ffff1ed1cb7 in zend_hash_reverse_apply (ht=0x7ffff2221de0,
apply_func=0x7ffff1ecc31c <module_registry_cleanup>) at
/usr/src/debug/php5.2-200907182030/Zend/zend_hash.c:755
#25 0x00007ffff1ec4738 in zend_deactivate_modules () at
/usr/src/debug/php5.2-200907182030/Zend/zend.c:838
#26 0x00007ffff1e6cf1c in php_request_shutdown (dummy=0x0) at
/usr/src/debug/php5.2-200907182030/main/main.c:1463
#27 0x00007ffff1f46775 in php_apache_request_dtor (r=0x7ffff87edd18) at
/usr/src/debug/php5.2-200907182030/sapi/apache2handler/sapi_apache2.c:47
2
#28 0x00007ffff1f46fe6 in php_handler (r=0x7ffff87edd18) at
/usr/src/debug/php5.2-200907182030/sapi/apache2handler/sapi_apache2.c:64
4
#29 0x00007ffff7fd9600 in ap_run_handler (r=0x7ffff87edd18) at
/usr/src/debug/httpd-2.2.11/server/config.c:158
#30 0x00007ffff7fdce98 in ap_invoke_handler (r=0x7ffff87edd18) at
/usr/src/debug/httpd-2.2.11/server/config.c:372
#31 0x00007ffff7fe852e in ap_process_request (r=0x7ffff87edd18) at
/usr/src/debug/httpd-2.2.11/modules/http/http_request.c:282
#32 0x00007ffff7fe5328 in ap_process_http_connection (c=0x7ffff87e7ed8)
at /usr/src/debug/httpd-2.2.11/modules/http/http_core.c:190
#33 0x00007ffff7fe1048 in ap_run_process_connection (c=0x7ffff87e7ed8)
at /usr/src/debug/httpd-2.2.11/server/connection.c:43
#34 0x00007ffff7fecf78 in child_main (child_num_arg=<value optimized
out>) at /usr/src/debug/httpd-2.2.11/server/mpm/prefork/prefork.c:650
#35 0x00007ffff7fed1f6 in make_child (s=0x7ffff8212f90, slot=0) at
/usr/src/debug/httpd-2.2.11/server/mpm/prefork/prefork.c:690
#36 0x00007ffff7fed853 in ap_mpm_run (_pconf=<value optimized out>,
plog=<value optimized out>, s=<value optimized out>) at
/usr/src/debug/httpd-2.2.11/server/mpm/prefork/prefork.c:966
#37 0x00007ffff7fc56d0 in main (argc=14, argv=0x7fffffffe128) at
/usr/src/debug/httpd-2.2.11/server/main.c:740
(gdb) frame 3
#3  0x00007ffff1d3d24c in php_pcre_match_impl (pce=0x7ffff8bd8360,
subject=0x7ffff8b998a8
"__HTTP_Session2_Info|i:2;__HTTP_Session2_Idle|i:3600;__HTTP_Session2_Id
le_TS|i:1247953764;user_id|s:1:\"6\";audit_user|N;", 
    subject_len=119, return_value=0x7ffff87b99f0, subpats=0x0, global=0,
use_flags=0, flags=0, start_offset=0) at
/usr/src/debug/php5.2-200907182030/ext/pcre/php_pcre.c:603
603		offsets = (int *)safe_emalloc(size_offsets, sizeof(int), 0);


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-07-29 12:14 UTC] timj@php.net
N.B. this occurs with both apache2 and CGI SAPIs.
 [2009-07-29 12:30 UTC] jani@php.net
In the future: PLEASE add the backtraces in separate comments. Now it's pretty hard to see which is which. 
 [2009-07-29 12:31 UTC] jani@php.net
And as expected: We really need proper, short, reproducing script. Now the problem might be anywhere..
 [2009-08-11 05:16 UTC] jani@php.net
NEVER ever email me privately test cases. Here's the script you sent me:

<?php

/*
CREATE TABLE `_session_data` (
  `id` char(32) NOT NULL,
  `expiry` int(10) unsigned NOT NULL,
  `data` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
*/

require_once 'HTTP/Session2.php';

$dsn = 'mysqli://user:pass@localhost/dbname';

$options = array();
$options['dsn']   = $dsn;
$options['table'] = '_session_data';

HTTP_Session2::setContainer('MDB2', $options);
HTTP_Session2::start('mysess');

?>

Installed PEAR packages to make it happen:
HTTP_Session2      0.7.2   beta
MDB2               2.5.0b2 beta
MDB2_Driver_mysqli 1.5.0b2 beta 
 
 [2009-08-11 22:00 UTC] timj@php.net
OK, for the record then, that case was reproducible for me with 5.2.11-dev snap 200908101630. Backtrace similar to the first one opening the bug.
 [2009-09-04 11:30 UTC] timj@php.net
Further info: the crash does NOT occur if the DSN string is changed to "mysql://..." instead of "mysqli://..." (this also seemed to be the case in similar bug #48922)
 [2009-09-16 02:26 UTC] sriram dot natarajan at gmail dot com
i just tried a simple php with mdb2/http_session2  with the latest php snapshot and was not able to reproduce this issue. is there some thing else required to reproduce this issue ?

here is the simple script that i had to try it out

<?php
require_once 'MDB2.php';
require_once 'HTTP/Session2.php';

$dsn = 'mysqli://root:@localhost/mysql';
$mdb2 =& MDB2::singleton($dsn);
$mdb2->loadModule('Manager');
$mdb2->loadModule('Extended');

$db = $mdb2->connect($dsn);
$table_fields = array
(
   'id'     =>  array(
                    'type' => 'text',
                    'length' => '32'),
   'data'   =>  array(
                    'type' => 'text',
                    'length' => '32'),
   'skey'   =>  array(
                    'type' => 'text',
                    'length' => '32'),
   'expiry' =>  array(
                    'type' => 'integer',
                    'notnull' => 1,
                    'unsigned' => 0),
);
$table_constraints = array(
    'primary' => true,
    'fields' => array (
                'id' => array()),
);
$s = $mdb2->createTable('session_data', $table_fields);
if (PEAR::isError($s)) {
   die($s->getMessage() . ', ' . $s->getDebugInfo());
}
$mdb2->createConstraint('session_data', 'primary_key',$table_constraints);
$mdb2->createSequence('primary_key');

$options = array();
$options['dsn']   = $dsn;
$options['table'] = 'session_data';

HTTP_Session2::setContainer('MDB2', $options);
HTTP_Session2::start('MySESS');
HTTP_Session2::set('variable', 'The string');

?>
 [2009-09-16 06:01 UTC] timj@php.net
sriram:
a) can you specify exactly which snapshot you use so that I can confirm/deny what you say
b) did you try my test script? what does that do? why did you make up a new one? 
 [2009-09-16 18:19 UTC] sriram dot natarajan at gmail dot com
i just took the latest php snapshot from http://snaps.php.net and tried it out. if you notice, my script is just a completion of your script - i just filled in some missing pieces in your script - like creating the table etc . 

i am also using mysql 5.1.30
 [2009-09-18 19:43 UTC] ulf at ladb dot unm dot edu
Hi,

Is this bug still under investigation? Just wondering because 5.2.9 is the last version of PHP that works with Wordpress/MySQL without crashing Apache.
Thanks.
 [2009-09-24 17:48 UTC] srinatar@php.net
i do have a wordpress running with php 5.2.11 for my site and i don't have any issues. if you do notice with the latest php build, if you can provide a test case to reproduce this bug that would be useful.

as i noted earlier, i was not able to reproduce this bug with the provided test case here. 
 [2009-09-24 19:32 UTC] srinatar@php.net
unable to reproduce with the earlier provided test case. so, need more information to reproduce / investigate this bug . also, would be useful to know if this still happens with either 5.2.11 (or latest svn snapshot)
 [2009-09-26 10:54 UTC] timj@php.net
1. Still segfaults for me with the release version of 5.2.11, with MySQLi connection (mysql client libs and server 5.1.37).
 -> Sriram, I also tried with your test script (just to make sure there wasn't a subtle difference from mine) and it also segfaulted.
 -> Segfault is still in the same place as originally.

2. snap-200909261030 doesn't build atm (error in mysqli_api)

What more info can I give to assist?

 [2009-11-08 19:10 UTC] timj@php.net
After spending an enormous amount of time testing endless combinations of compile and runtime options, I have hopefully found the key to solving this obscure bug. The segfault only happens specifically if the following is true:

- the mbstring extension is enabled, *AND*
- the mssql extension is enabled (particularly weird because the test script does not use mssql in any way)

In the hope of making the reproduction scenario more robust, I have pared down the configure line to a minimum and here is the exact environment, from source tarball, which I can reproduce it in:

OS: Fedora 11 x86_64 (fully updated as at 2009-11-08)
Notable dependencies:
mysql-devel-5.1.37-1.fc11.x86_64
freetds-devel-0.82-5.fc11.x86_64
gcc version 4.4.1 20090725 (Red Hat 4.4.1-2) (GCC)

Download snapshot 200911070930 from snaps.php.net
tar -jxf php5.2-200911070930.tar.bz2
cd php5.2-200911070930
./configure --includedir=/usr/include --libdir=/usr/lib64 --with-libdir=lib64 --without-pear --with-mysqli=shared,/usr/bin/mysql_config --enable-mbstring=shared --enable-mbregex --with-mssql=shared,/usr
make -j3
make install # as root

create /usr/local/etc/php.ini containing only the following:
extension=mbstring.so
extension=mssql.so
extension=mysqli.so
include_path=/path/to/pear/php

$ /usr/local/bin/php -c /usr/local/etc/php.ini php-bug49098.php # script posted on 11 Aug
Segmentation fault

Commenting out EITHER "extension=mbstring.so" or "extension=mssql.so" in /usr/local/etc/php.ini stops the segfault.


Can anyone else now reproduce this with the above environment? Is there any other information about the environment that I need to provide?
 [2009-11-08 21:11 UTC] srinatar@php.net
thanks for taking time and trying to reproduce this issue. can u kindly 
provide / attach stack trace when this issue happens... this would help 
us identify us as to what is happening at ur end..

u can enable core dump by doing some thing like
ulimit -c unlimited

now, u can run your program to generate core dump and provide us the 
stack trace as mentioned in this below link..

http://bugs.php.net/bugs-generating-backtrace.php
 [2009-11-08 22:43 UTC] timj@php.net
With my original compile as per instructions above (the compiler got -O2 by default):

#0  _zend_mm_alloc_int (heap=0x9e32b0, size=12)
    at /path/to/php5.2-200911070930/Zend/zend_alloc.c:1785
#1  0x000000000048227e in php_pcre_match_impl (pce=<value optimized out>, 
    subject=<value optimized out>, subject_len=<value optimized out>, 
    return_value=<value optimized out>, subpats=0x0, global=0, use_flags=0, 
    flags=<value optimized out>, start_offset=0)
    at /path/to/php5.2-200911070930/ext/pcre/php_pcre.c:603
#2  0x0000000000482ccd in php_do_pcre_match (ht=2, return_value=0xd584a0, 
    return_value_ptr=<value optimized out>, this_ptr=<value optimized out>, 
    return_value_used=<value optimized out>, global=0)
    at /path/to/php5.2-200911070930/ext/pcre/php_pcre.c:513
#3  0x0000000000659303 in zend_do_fcall_common_helper_SPEC (
    execute_data=0x7fffffffc420)
    at /path/to/php5.2-200911070930/Zend/zend_vm_execute.h:200
#4  0x000000000065522c in execute (op_array=0xd83190)
    at /path/to/php5.2-200911070930/Zend/zend_vm_execute.h:92
#5  0x0000000000658c76 in zend_do_fcall_common_helper_SPEC (
    execute_data=0x7fffffffc740)
    at /path/to/php5.2-200911070930/Zend/zend_vm_execute.h:234
#6  0x000000000065522c in execute (op_array=0xd37808)
    at /path/to/php5.2-200911070930/Zend/zend_vm_execute.h:92
#7  0x0000000000658c76 in zend_do_fcall_common_helper_SPEC (
    execute_data=0x7fffffffd660)
 [2009-11-08 22:44 UTC] timj@php.net
Recompiled with --enable-debug and -O1, the backtrace is very similar to that reported right at the start of the bug, and not very helpful:

#0  0x0000000000600d2d in _zend_mm_free_int ()
#1  0x0000000000600fc9 in _efree ()
#2  0x00000000005b651f in php_version_compare ()
#3  0x00000000005b6596 in zif_version_compare ()
#4  0x000000000063df7a in zend_do_fcall_common_helper_SPEC ()
#5  0x000000000063e53f in ZEND_DO_FCALL_SPEC_CONST_HANDLER ()
#6  0x000000000063a63d in execute ()
#7  0x000000000063e076 in zend_do_fcall_common_helper_SPEC ()
#8  0x000000000063e453 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER ()
#9  0x000000000063a63d in execute ()
#10 0x000000000063e076 in zend_do_fcall_common_helper_SPEC ()
#11 0x000000000063e453 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER ()
#12 0x000000000063a63d in execute ()
#13 0x000000000063e076 in zend_do_fcall_common_helper_SPEC ()
#14 0x000000000063e453 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER ()
#15 0x000000000063a63d in execute ()
#16 0x000000000063e076 in zend_do_fcall_common_helper_SPEC ()
#17 0x000000000063e453 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER ()
#18 0x000000000063a63d in execute ()
#19 0x000000000060ff69 in zend_call_function ()
#20 0x000000000061021b in call_user_function_ex ()
#21 0x00000000006103ef in call_user_function ()
#22 0x00000000005146ac in ps_call_handler ()
#23 0x00000000005148f4 in ps_write_user ()
#24 0x000000000050e381 in php_session_flush ()
#25 0x000000000050f4f6 in zm_deactivate_session ()
#26 0x000000000061b4be in module_registry_cleanup ()
#27 0x0000000000623a51 in zend_hash_reverse_apply ()
#28 0x000000000061a1ff in zend_deactivate_modules ()
#29 0x00000000005db184 in php_request_shutdown ()
#30 0x0000000000683ecc in main ()

Now, what's really interesting is that with -O0 and the exact same configure options, the segfault doesn't happen. Maybe this helps to pinpoint the cause?
 [2009-11-08 23:08 UTC] timj@php.net
Compiling with -O0 and *without* --enable-debug gives a backtrace  which is almost (not quite) the same:

#0  0x00000000006bec94 in _zend_mm_free_int ()
#1  0x00000000006bfb06 in _efree ()
#2  0x00000000006546cf in php_version_compare ()
#3  0x000000000065474f in zif_version_compare ()
#4  0x000000000070a98a in zend_do_fcall_common_helper_SPEC ()
#5  0x000000000070e932 in ZEND_DO_FCALL_SPEC_CONST_HANDLER ()
#6  0x000000000070a480 in execute ()
#7  0x000000000070ab3b in zend_do_fcall_common_helper_SPEC ()
#8  0x000000000070b081 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER ()
#9  0x000000000070a480 in execute ()
#10 0x000000000070ab3b in zend_do_fcall_common_helper_SPEC ()
#11 0x000000000070b081 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER ()
#12 0x000000000070a480 in execute ()
#13 0x000000000070ab3b in zend_do_fcall_common_helper_SPEC ()
#14 0x000000000070b081 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER ()
#15 0x000000000070a480 in execute ()
#16 0x000000000070ab3b in zend_do_fcall_common_helper_SPEC ()
#17 0x000000000070b081 in ZEND_DO_FCALL_BY_NAME_SPEC_HANDLER ()
#18 0x000000000070a480 in execute ()
#19 0x00000000006d2340 in zend_call_function ()
#20 0x00000000006d0651 in call_user_function_ex ()
#21 0x00000000006d052c in call_user_function ()
#22 0x00000000005718c9 in ps_call_handler ()
#23 0x0000000000571d8c in ps_write_user ()
#24 0x000000000056ab00 in php_session_save_current_state ()
#25 0x000000000056e184 in php_session_flush ()
#26 0x0000000000570395 in zm_deactivate_session ()
#27 0x00000000006e7532 in module_registry_cleanup ()
#28 0x00000000006ecf0f in zend_hash_reverse_apply ()
#29 0x00000000006df855 in zend_deactivate_modules ()
#30 0x0000000000689690 in php_request_shutdown ()
#31 0x0000000000763bd4 in main ()
 [2009-11-09 17:22 UTC] jani@php.net
Try with valgrind:

# USE_ZEND_ALLOC=0 valgrind --leak-check=full sapi/cli/php yourscript.php

 [2009-11-10 23:11 UTC] timj@php.net
==23150== Invalid free() / delete / delete[]
==23150==    at 0x4A0633D: free (vg_replace_malloc.c:323)
==23150==    by 0xABA17B9: php_mysqli_set_error (mysqli.c:1004)
==23150==    by 0xABA61DD: zif_mysqli_real_connect (mysqli_api.c:1476)
==23150==    by 0x656BD2: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:200)
==23150==    by 0x652AFB: execute (zend_vm_execute.h:92)
==23150==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==23150==    by 0x652AFB: execute (zend_vm_execute.h:92)
==23150==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==23150==    by 0x652AFB: execute (zend_vm_execute.h:92)
==23150==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==23150==    by 0x652AFB: execute (zend_vm_execute.h:92)
==23150==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==23150==  Address 0xba0af20 is 0 bytes inside a block of size 1 free'd
==23150==    at 0x4A0633D: free (vg_replace_malloc.c:323)
==23150==    by 0xABA1348: zm_deactivate_mysqli (mysqli.c:711)
==23150==    by 0x63165B: module_registry_cleanup (zend_API.c:1976)
==23150==    by 0x63A3B3: zend_hash_reverse_apply (zend_hash.c:755)
==23150==    by 0x6301EC: zend_deactivate_modules (zend.c:838)
==23150==    by 0x5ED964: php_request_shutdown (main.c:1475)
==23150==    by 0x6A065B: main (php_cli.c:1343)
==23150== 
==23150== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 6 from 2)
==23150== malloc/free: in use at exit: 753 bytes in 4 blocks.
==23150== malloc/free: 52,204 allocs, 52,201 frees, 11,636,702 bytes allocated.
==23150== For counts of detected errors, rerun with: -v
==23150== searching for pointers to 4 not-freed blocks.
==23150== checked 746,032 bytes.
==23150== 
==23150== 
==23150== 1 bytes in 1 blocks are definitely lost in loss record 1 of 4
==23150==    at 0x4A0763E: malloc (vg_replace_malloc.c:207)
==23150==    by 0x616129: _estrdup (zend_alloc.c:2428)
==23150==    by 0xABA17C1: ???
==23150==    by 0xABA61DD: ???
==23150==    by 0x656BD2: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:200)
==23150==    by 0x652AFB: execute (zend_vm_execute.h:92)
==23150==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==23150==    by 0x652AFB: execute (zend_vm_execute.h:92)
==23150==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==23150==    by 0x652AFB: execute (zend_vm_execute.h:92)
==23150==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==23150==    by 0x652AFB: execute (zend_vm_execute.h:92)
==23150== 
==23150== LEAK SUMMARY:
==23150==    definitely lost: 1 bytes in 1 blocks.
==23150==      possibly lost: 0 bytes in 0 blocks.
==23150==    still reachable: 752 bytes in 3 blocks.
==23150==         suppressed: 0 bytes in 0 blocks.
==23150== Reachable blocks (those to which a pointer was found) are not shown.
==23150== To see them, rerun with: --leak-check=full --show-reachable=yes

 [2009-11-10 23:35 UTC] rasmus@php.net
Looks like an ext/mysqli problem, but I looked through the code and I don't see a case where MyG(error_msg) is free'ed without being NULL'ed or immediately re-allocated.  It isn't NULL'ed in the RSHUTDOWN, but it is NULL'ed in the RINIT, so there should be no way to get to php_mysqli_set_error() without it being either NULL or correctly allocated.


 [2009-11-11 08:48 UTC] jani@php.net
To narrow this down a bit: Does it happen with latest PHP 5.3 snapshot?
 [2009-11-11 20:41 UTC] timj@php.net
Yes it still segfaults in the same way in 5.3-snap200911111930. Essentially the same valgrind output.

Going back to the original issue, it started happening in 5.2.10. A diff of the "mysqli" directory between 5.2.9 and 5.2.10 shows only one change: mysqli_api.c in SVN r281844.
 [2009-11-11 22:48 UTC] timj@php.net
Reverting the change from r281844 doesn't seem to fix it (tested on 5.3-snap200911111930)
 [2009-11-11 22:50 UTC] jani@php.net
What's the valgrind output then, same as before?
 [2009-11-11 23:01 UTC] timj@php.net
Yep. Also checked on 5.2, just in case.

Here's some valgrind from 5.3 for info:

==17517== Invalid free() / delete / delete[]
==17517==    at 0x4A0633D: free (vg_replace_malloc.c:323)
==17517==    by 0xABA17B9: php_mysqli_set_error (mysqli.c:1004)
==17517==    by 0xABA61DD: zif_mysqli_real_connect (mysqli_api.c:1476)
==17517==    by 0x656BD2: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:200)
==17517==    by 0x652AFB: execute (zend_vm_execute.h:92)
==17517==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==17517==    by 0x652AFB: execute (zend_vm_execute.h:92)
==17517==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==17517==    by 0x652AFB: execute (zend_vm_execute.h:92)
==17517==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==17517==    by 0x652AFB: execute (zend_vm_execute.h:92)
==17517==    by 0x656545: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:234)
==17517==  Address 0xba0af20 is 0 bytes inside a block of size 1 free'd
==17517==    at 0x4A0633D: free (vg_replace_malloc.c:323)
==17517==    by 0xABA1348: zm_deactivate_mysqli (mysqli.c:711)
==17517==    by 0x63165B: module_registry_cleanup (zend_API.c:1976)
==17517==    by 0x63A3B3: zend_hash_reverse_apply (zend_hash.c:755)
==17517==    by 0x6301EC: zend_deactivate_modules (zend.c:838)
==17517==    by 0x5ED964: php_request_shutdown (main.c:1475)
==17517==    by 0x6A065B: main (php_cli.c:1343)
==17517== 


 [2009-11-11 23:14 UTC] rasmus@php.net
Could you set a gdb breakpoint on the php_mysqli_set_error call and show the arguments passed to it?

I still don't see anything in the code around that part that would cause this though.  It feels like something else is stepping on global memory here, but it is too consistent to be random memory corruption.

Would be nice if someone else could reproduce it.

 [2009-11-11 23:30 UTC] timj@php.net
Breakpoint 1, php_mysqli_set_error (mysql_errno=0, mysql_err=0xbd1f77 "")
    at /path/to/php5.2-200911070930/ext/mysqli/mysqli.c:1001

 [2009-11-11 23:38 UTC] timj@php.net
To be more specific, php_mysqli_set_error gets called twice before crashing with the same params:

Starting program: /usr/local/bin/php -c /usr/local/etc php-bug49098.php
[Thread debugging using libthread_db enabled]

Breakpoint 1, php_mysqli_set_error (mysql_errno=0, mysql_err=0xbd1f77 "")
    at /path/to/php5.2-200911070930/ext/mysqli/mysqli.c:1001
1001	{
(gdb) c
Continuing.
ok <-- *** this is program output to stdout, everything is OK here

Breakpoint 1, php_mysqli_set_error (mysql_errno=0, mysql_err=0xbd1f77 "")
    at /path/to/php5.2-200911070930/ext/mysqli/mysqli.c:1001
1001	{
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
_zend_mm_alloc_int (heap=0x9e02b0, size=12)
    at /path/to/php5.2-200911070930/Zend/zend_alloc.c:1785
1785				heap->cache[index] = best_fit->prev_free_block;

 [2009-11-11 23:38 UTC] rasmus@php.net
Could you try this patch and see if it changes anything?

Index: mysqli_nonapi.c
===================================================================
--- mysqli_nonapi.c	(revision 290565)
+++ mysqli_nonapi.c	(working copy)
@@ -46,7 +46,11 @@
 	if (MyG(error_msg)) {
 		efree(MyG(error_msg));
 	}
-	MyG(error_msg) = estrdup(mysql_err);
+	if(mysql_err) { 
+		MyG(error_msg) = estrdup(mysql_err);
+	} else {
+		MyG(error_msg) = NULL;
+	}
 }
 /* }}} */
 [2009-11-11 23:48 UTC] timj@php.net
Nope, still the same result. (back on the 5.3 snapshot now)
 [2009-11-11 23:55 UTC] timj@php.net
Stepping through the code though, that patch wouldn't have made any difference. On the final incantation of php_mysqli_set_error before crash, estrdup() still gets called:

Breakpoint 1, php_mysqli_set_error (mysql_errno=0, mysql_err=0x10325a7 "") at /path/to/php5.3-200911111930/ext/mysqli/mysqli_nonapi.c:44
44	{
(gdb) step
45		MyG(error_no) = mysql_errno;
(gdb) step
44	{
(gdb) step
45		MyG(error_no) = mysql_errno;
(gdb) step
46		if (MyG(error_msg)) {
(gdb) step
47			efree(MyG(error_msg));
(gdb) next
49		if(mysql_err) { 
(gdb) step
50			MyG(error_msg) = estrdup(mysql_err);

 [2009-11-11 23:59 UTC] timj@php.net
I'm not sure if this is useful/correct, but at first pass this stops the crash:

--- ext/mysqli/mysqli_nonapi.c.orig	2009-10-15 23:34:41.000000000 +0100
+++ ext/mysqli/mysqli_nonapi.c	2009-11-11 23:56:40.271496635 +0000
@@ -46,7 +46,11 @@
 	if (MyG(error_msg)) {
 		efree(MyG(error_msg));
 	}
-	MyG(error_msg) = estrdup(mysql_err);
+	if(mysql_errno!=0) { 
+		MyG(error_msg) = estrdup(mysql_err);
+	} else {
+		MyG(error_msg) = NULL;
+	}
 }
 /* }}} */

 [2009-11-12 01:09 UTC] svn@php.net
Automatic comment from SVN on behalf of rasmus
Revision: http://svn.php.net/viewvc/?view=revision&revision=290570
Log: Fix bug #49098
 [2009-11-12 01:10 UTC] rasmus@php.net
Should be fixed now in svn.  Please verify.
 [2009-11-12 07:16 UTC] timj@php.net
Confirmed works for me. Below tested on PHP 5.2 which also seems to work - could you fix it on that branch too?:

--- ext/mysqli/mysqli.c.orig	2009-07-17 13:17:25.000000000 +0100
+++ ext/mysqli/mysqli.c	2009-11-12 07:10:19.054055576 +0000
@@ -1003,7 +1003,11 @@
 	if (MyG(error_msg)) {
 		efree(MyG(error_msg));
 	}
-	MyG(error_msg) = estrdup(mysql_err);
+	if(mysql_err && *mysql_err) {
+		MyG(error_msg) = estrdup(mysql_err);
+	} else {
+		MyG(error_msg) = NULL;
+	}
 }
 /* }}} */

Many thanks Rasmus (and to Jani/Sriram for your help). 
 [2009-11-12 08:20 UTC] svn@php.net
Automatic comment from SVN on behalf of rasmus
Revision: http://svn.php.net/viewvc/?view=revision&revision=290573
Log: Fix for bug #49098
 [2009-11-12 17:48 UTC] svn@php.net
Automatic comment from SVN on behalf of johannes
Revision: http://svn.php.net/viewvc/?view=revision&revision=290608
Log: Merge 290570 (Fix bug #49098). (Rasmus)
 [2010-10-25 00:07 UTC] nn at tronix dot pl
I think the BUG still exists.
I have custom session handler based on PostgreSQL queries.
Any version above 5.2.9 segfaults immediately after I open the application in the browser.
As soon as custom session handler is disabled - everything is working fine.

I think that mb_string is important here, not mssql.

Brgs
Norbert
 [2010-11-10 21:33 UTC] timj@php.net
-Assigned To: +Assigned To: timj
 [2010-11-10 21:34 UTC] timj@php.net
This particular bug was definitely fixed in PHP 5.2.12. If you think you can reproduce it in the latest release of PHP, I would suggest opening a new bug with full details.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 08:01:29 2024 UTC