Aaaaaaaaaaargh!
When I run the following code...
----------------------------------------------
char fname[256];
zval **retval;
zval *zfname;
strcpy(fname, "rand");
zend_printf("Step 1...\n");
MAKE_STD_ZVAL(zfname);
zend_printf("Step 2...\n");
ZVAL_STRING(zfname, fname, 1);
zend_printf("Step 3...\n");
TSRMLS_FETCH();
zend_printf("Step 4...\n");
if (call_user_function_ex(CG(function_table), NULL,
zfname, retval, 0, NULL, 0,
`NULL` TSRMLS_DC) == SUCCESS)
{
zend_printf("The function has ben called.\n");
}
-----------------------------------------------
... i get:
Step 1...
Step 2...
Step 3...
Step 4...
Segmentation fault
Could someone tell me what I'm doing wrong?
Thank you very much,
Oriol
My code is just as bad, but I remember that it used to work:
PHP_FUNCTION(jtemplate_set_root)
{
zval **z_root_dir;
char *root_dir = NULL;
int argc = ZEND_NUM_ARGS();
zval func;
zval *retval = NULL;
zval *args[1];
if (argc < 0 || argc > 1 ||
zend_get_parameters_ex(argc, &z_root_dir) == FAILURE) {
WRONG_PARAM_COUNT;
}
if (argc > 0) {
convert_to_string_ex(z_root_dir);
root_dir = estrndup(Z_STRVAL_PP(z_root_dir),
Z_STRLEN_PP(z_root_dir));
} else {
root_dir = estrndup(".", sizeof(".") - 1);
}
INIT_ZVAL(func);
ZVAL_STRING(&func, "is_dir", 1);
MAKE_STD_ZVAL(args[0]);
ZVAL_STRING(args[0], root_dir, 1);
MAKE_STD_ZVAL(retval);
/* check to see if the directory really exists and that is a real
directory */
if (call_user_function(EG(function_table), NULL, &func, retval, 1,
args TSRMLS_CC) == FAILURE) {
zend_error(E_ERROR, "%s(): could not call is_dir().",
get_active_function_name(TSRMLS_C));
}
if (Z_TYPE_P(retval) == IS_BOOL && Z_LVAL_P(retval) == 0) {
ZVAL_STRING(&func, "halt", 1);
ZVAL_STRING(args[0], "no such directory", 1);
call_user_function(NULL, &getThis(), &func, retval, 1,
args TSRMLS_CC);
zval_dtor(&func);
}
efree(root_dir);
zval_dtor(retval);
zval_ptr_dtor(&args[0]);
add_property_stringl(getThis(), "root", Z_STRVAL_PP(z_root_dir),
Z_STRLEN_PP(z_root_dir), 1);
ZEND_PUTS(get_active_function_name(TSRMLS_C));
RETURN_TRUE;
}
Yes, this is nasty ;)
Cheers,
Joao
I see two notable problems, though there may be more:
-
TSRMLS_DC should be TSRMLS_CC _DC is only used for function
declarations, _CC is used for passing the tsrm parameter to it. (Did you
configure with --enable-maintainer-zts [ or --enable-experimental-zts if
this is PHP4 ]? ) -
You need to either allocate the zval* for retval or (better) define
retval as a zval* (not zval**) and pass it as &retval. The way you have it
now will have call_user_func attempt to overwrite the data at the address
pointed to by retval (which at the moment is undefined). This is probably
what is specifically causing your segfault here.
-Sara
"Oriol" omagrane@anthill.es wrote in message
news:000701c334ed$9850c6f0$0601a8c0@pii...
Aaaaaaaaaaargh! When I run the following code... ---------------------------------------------- char fname[256]; zval **retval; zval *zfname; strcpy(fname, "rand"); zend_printf("Step 1...\n"); MAKE_STD_ZVAL(zfname); zend_printf("Step 2...\n"); ZVAL_STRING(zfname, fname, 1); zend_printf("Step 3...\n"); TSRMLS_FETCH(); zend_printf("Step 4...\n"); if (call_user_function_ex(CG(function_table), NULL, zfname, retval, 0, NULL, 0, `NULL` TSRMLS_DC) == SUCCESS) { zend_printf("The function has ben called.\n"); } ----------------------------------------------- ... i get: Step 1... Step 2... Step 3... Step 4... Segmentation fault Could someone tell me what I'm doing wrong? Thank you very much, Oriol