I've run into a segmentation fault situation when calling call_user_function()
in an extension I'm developing. I can reproduce the fault reliably when trying
to pass 4 arguments to my user function. The strange (to me anyway) thing is
that it doesn't crash when passing 3 or fewer arguments. Can anyone point out
what might be causing this error? Here's my source code:
void async_callback(getdns_context *context,
getdns_callback_type_t callbackType,
getdns_dict *response,
void *userArg, getdns_transaction_t transID)
{
int phpResult = 0;
zval *userArgs, **hashData;
zval *clientArgs[4];
zval cbType, dictVal, funcName, retVal, transIDVal;
char *phpCallback = NULL;
HashTable *arrayHash;
HashPosition hashPtr;
userArgs = (zval *) userArg;
arrayHash = Z_ARRVAL_P(userArgs);
zend_hash_internal_pointer_reset_ex(arrayHash, &hashPtr);
if (zend_hash_get_current_data_ex(arrayHash, (void**) &hashData, &hashPtr)
== SUCCESS) {
phpCallback = (char *) Z_STRVAL_PP(hashData);
}
else {
php_error_docref(NULL TSRMLS_DC, E_ERROR, "Invalid callback
parameters!");
return;
}
ZVAL_STRING(&funcName, phpCallback, 0);
clientArgs[0] = &dictVal;
ZVAL_LONG(clientArgs[0], (long) response);
clientArgs[1] = &cbType;
ZVAL_LONG(clientArgs[1], (long) callbackType);
clientArgs[2] = userArgs;
clientArgs[3] = &transIDVal;
ZVAL_STRING(clientArgs[3], "0000000000000000", 1);
phpResult = call_user_function(EG(function_table), NULL,
&funcName, &retVal, 4, clientArgs TSRMLS_DC);
if (phpResult == FAILURE) {
php_error_docref(NULL TSRMLS_DC, E_ERROR, "Callback failed!");
}
}
Here's the stack trace produced when running my PHP client program that calls
into this extension and passes the name of the user function:
Program received signal SIGSEGV, Segmentation fault.
0x00000000006c8570 in gc_remove_from_buffer (root=0x7ffff5a364f4
<evmap_io_del+212>) at /projects/php/php-5.6.5/Zend/zend_gc.h:189
189 root->next->prev = root->prev;
(gdb) bt
#0 0x00000000006c8570 in gc_remove_from_buffer (root=0x7ffff5a364f4
<evmap_io_del+212>) at /projects/php/php-5.6.5/Zend/zend_gc.h:189
#1 gc_remove_zval_from_buffer (zv=zv@entry=0x7fffffffa350) at
/projects/php/php-5.6.5/Zend/zend_gc.c:265
#2 0x000000000069a6d8 in i_zval_ptr_dtor (zval_ptr=0x7fffffffa350) at
/projects/php/php-5.6.5/Zend/zend_execute.h:78
#3 zend_vm_stack_clear_multiple (nested=0) at
/projects/php/php-5.6.5/Zend/zend_execute.h:308
#4 zend_call_function (fci=fci@entry=0x7fffffffa280, fci_cache=<optimized
out>, fci_cache@entry=0x0)
at /projects/php/php-5.6.5/Zend/zend_execute_API.c:886
#5 0x000000000069abae in call_user_function_ex
(function_table=function_table@entry=0xdfd130, object_pp=<optimized out>,
function_name=<optimized out>,
retval_ptr_ptr=retval_ptr_ptr@entry=0x7fffffffa318, param_count=<optimized
out>, params=params@entry=0x7ffff7fd40a0, no_separation=no_separation@entry=1,
symbol_table=symbol_table@entry=0x0) at
/projects/php/php-5.6.5/Zend/zend_execute_API.c:617
#6 0x000000000069ac02 in call_user_function (function_table=0xdfd130,
object_pp=object_pp@entry=0x0,
function_name=function_name@entry=0x7fffffffa390,
retval_ptr=retval_ptr@entry=0x7fffffffa3b0,
param_count=param_count@entry=4, params=params@entry=0x7fffffffa3f0)
at /projects/php/php-5.6.5/Zend/zend_execute_API.c:590
#7 0x00007ffff60aab23 in async_callback (context=<optimized out>,
callbackType=GETDNS_CALLBACK_COMPLETE, response=0xff6860,
userArg=0x7ffff7fcf930,
transID=<optimized out>) at /projects/getdns-php-bindings/phpgetdns.c:1191
#8 0x00007ffff57ed682 in ub_process () from
/usr/lib/x86_64-linux-gnu/libunbound.so.2
#9 0x00007ffff5c780fa in priv_getdns_context_ub_read_cb (userarg=0xf476d0) at
./context.c:985
#10 0x00007ffff5a278b4 in event_base_loop () from
/usr/lib/x86_64-linux-gnu/libevent_core-2.0.so.5
#11 0x00007ffff60adc03 in zif_php_getdns_context_run (ht=<optimized out>,
return_value=0x7ffff7fd3d40, return_value_ptr=<optimized out>,
this_ptr=<optimized out>, return_value_used=<optimized out>) at
/projects/getdns-php-bindings/phpgetdns.c:3606
#12 0x000000000074d68e in zend_do_fcall_common_helper_SPEC
(execute_data=<optimized out>) at
/projects/php/php-5.6.5/Zend/zend_vm_execute.h:558
#13 0x00000000006e4108 in execute_ex (execute_data=0x7ffff7f9a590) at
/projects/php/php-5.6.5/Zend/zend_vm_execute.h:363
#14 0x00000000006ab330 in zend_execute_scripts (type=type@entry=8,
retval=retval@entry=0x0, file_count=file_count@entry=3)
at /projects/php/php-5.6.5/Zend/zend.c:1341
#15 0x0000000000649255 in php_execute_script
(primary_file=primary_file@entry=0x7fffffffcac0) at
/projects/php/php-5.6.5/main/main.c:2584
#16 0x000000000074f2ef in do_cli (argc=2, argv=0xdfc540) at
/projects/php/php-5.6.5/sapi/cli/php_cli.c:994
#17 0x0000000000426670 in main (argc=2, argv=0xdfc540) at
/projects/php/php-5.6.5/sapi/cli/php_cli.c:1378
(gdb) up
#1 gc_remove_zval_from_buffer (zv=zv@entry=0x7fffffffa350) at
/projects/php/php-5.6.5/Zend/zend_gc.c:265
265 GC_REMOVE_FROM_BUFFER(root_buffer);
(gdb) up
#2 0x000000000069a6d8 in i_zval_ptr_dtor (zval_ptr=0x7fffffffa350) at
/projects/php/php-5.6.5/Zend/zend_execute.h:78
78 GC_REMOVE_ZVAL_FROM_BUFFER(zval_ptr);
(gdb) up
#3 zend_vm_stack_clear_multiple (nested=0) at
/projects/php/php-5.6.5/Zend/zend_execute.h:308
308 i_zval_ptr_dtor(q ZEND_FILE_LINE_CC TSRMLS_CC);
(gdb) up
#4 zend_call_function (fci=fci@entry=0x7fffffffa280, fci_cache=<optimized
out>, fci_cache@entry=0x0)
at /projects/php/php-5.6.5/Zend/zend_execute_API.c:886
886 zend_vm_stack_clear_multiple(0 TSRMLS_CC);
(gdb) up
#5 0x000000000069abae in call_user_function_ex
(function_table=function_table@entry=0xdfd130, object_pp=<optimized out>,
function_name=<optimized out>,
retval_ptr_ptr=retval_ptr_ptr@entry=0x7fffffffa318, param_count=<optimized
out>, params=params@entry=0x7ffff7fd40a0, no_separation=no_separation@entry=1,
symbol_table=symbol_table@entry=0x0) at
/projects/php/php-5.6.5/Zend/zend_execute_API.c:617
617 return zend_call_function(&fci, NULL TSRMLS_CC);
(gdb) up
#6 0x000000000069ac02 in call_user_function (function_table=0xdfd130,
object_pp=object_pp@entry=0x0,
function_name=function_name@entry=0x7fffffffa390,
retval_ptr=retval_ptr@entry=0x7fffffffa3b0,
param_count=param_count@entry=4, params=params@entry=0x7fffffffa3f0)
at /projects/php/php-5.6.5/Zend/zend_execute_API.c:590
590 ex_retval = call_user_function_ex(function_table, object_pp,
function_name, &local_retval_ptr, param_count, params_array, 1, NULL TSRMLS_CC);
(gdb) up
#7 0x00007ffff60aab23 in async_callback (context=<optimized out>,
callbackType=GETDNS_CALLBACK_COMPLETE, response=0xff6860,
userArg=0x7ffff7fcf930,
transID=<optimized out>) at /projects/getdns-php-bindings/phpgetdns.c:1191
1191 phpResult = call_user_function(EG(function_table), NULL,
(gdb)
Any thoughts? From what I can see in gdb the variable with value 0x7fffffffa350
is the second element of the clientArgs array:
(gdb) print clientArgs
$1 = {0x7fffffffa370, 0x7fffffffa350, 0x7ffff7fcf930, 0x7fffffffa3d0}
(gdb)
Thank you,
Scott
--
PECL development discussion Mailing List (http://pecl.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php