Overloading methods : segfaults
| From: | Andrey Demenev | Date: | Mon, 27 Sep 2004 14:04:55 +0000 |
| Subject: | Overloading methods : segfaults | ||
| Groups: | php.pecl.dev | ||
| Request: | Send a blank email to pecl-dev+get-1396@lists.php.net to get a copy of this message | ||
Hello
Not sure if this is appropriate list. Maybe internals?
I am writing a PHP extension implementing an embedded Ruby interpreter
(http://www.ruby-lang.org/). It requires method and property overloading.
Overloading was successfully implemented in ZE1 version of extension. When
porting the extension to ZE2, I have faced with segfaults when calling
overloaded methods (no problem with property overloading). I suspected that
the problem may be caused by external libraries, and wrote a minimalistic
test extension (see attachment). It simply prints out name of called method,
but the problem is the same.
Backtrace :
-----------------------8<---------------------------------------
[andrey@andrey php5-STABLE-200409271030]# gdb sapi/cli/php
GNU gdb 6.0-2mdk (Mandrake Linux)
Copyright 2003 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i586-mandrake-linux-gnu"...Using host libthread_db
library "/lib/tls/libthread_db.so.1".
(gdb) r
Starting program: /home/andrey/Documents/php5-STABLE-200409271030/sapi/cli/php
<?php
$o=new Test;
$o->someMethod();
?>
someMethod called
Program received signal SIGSEGV, Segmentation fault.
0x080dfbd5 in shutdown_memory_manager (silent=0, full_shutdown=0)
at /home/andrey/Documents/php5-STABLE-200409271030/Zend/zend_alloc.c:485
485 for (j=0; j<AG(cache_count)[i]; j++) {
(gdb) bt
#0 0x080dfbd5 in shutdown_memory_manager (silent=0, full_shutdown=0)
at /home/andrey/Documents/php5-STABLE-200409271030/Zend/zend_alloc.c:485
#1 0x080c04c6 in php_request_shutdown (dummy=0x0)
at /home/andrey/Documents/php5-STABLE-200409271030/main/main.c:1223
#2 0x0811f16f in main (argc=1, argv=0xbffff624)
at /home/andrey/Documents/php5-STABLE-200409271030/sapi/cli/php_cli.c:1046
(gdb)
----------------------------->8-------------------------------------------------
Mandrake Linux 10 Official, PHP 5 stable built on Sep 27, 2004 10:30 GMT
gcc version 3.3.2 (Mandrake Linux 10.0 3.3.2-6mdk)
Could someone familiar with ZE2 internals please take a look at the source? Am
I missing something? Should I post this to internals list? File a bug report?
--
Andrey Demenev aka blindman
#ifndef PHP_TEST_H #define PHP_TEST_H #include "php.h" extern zend_module_entry test_module_entry; #define phpext_test_ptr &test_module_entry PHP_MINIT_FUNCTION(test); ZEND_API zend_object_value test_objects_new(zend_class_entry * TSRMLS_DC); #endif #include "php.h" #include "php_test.h" static union _zend_function *test_method_get(zval *object, char *method, int method_len TSRMLS_DC); int test_method_call (char *method, INTERNAL_FUNCTION_PARAMETERS); ZEND_API zend_object_value test_objects_new(zend_class_entry *class_type TSRMLS_DC); PHP_MINIT_FUNCTION(test); zend_class_entry *test_class_entry; static zend_object_handlers test_object_handlers; zend_module_entry test_module_entry = { STANDARD_MODULE_HEADER, "test", NULL, PHP_MINIT(test), NULL, NULL, NULL, NULL, "0.1", STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_RUBY ZEND_GET_MODULE(test) #endif PHP_MINIT_FUNCTION(test) { zend_class_entry _test_class_entry; INIT_CLASS_ENTRY(_test_class_entry, "test", NULL); _test_class_entry.create_object = test_objects_new; test_class_entry = zend_register_internal_class(&_test_class_entry TSRMLS_CC); memcpy(&test_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); test_object_handlers.call_method = test_method_call; test_object_handlers.get_method = test_method_get; } ZEND_API zend_object_value test_objects_new(zend_class_entry *class_type TSRMLS_DC) { zend_object_value retval; zend_object *intern; zval *tmp; intern = emalloc(sizeof(zend_object)); intern->ce = class_type; intern->in_get = 0; intern->in_set = 0; ALLOC_HASHTABLE(intern->properties); zend_hash_init(intern->properties, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy( intern->properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); retval.handle = zend_objects_store_put(intern, NULL, NULL, NULL TSRMLS_CC); retval.handlers = &test_object_handlers; return retval; } static union _zend_function *test_method_get(zval *object, char *method, int method_len TSRMLS_DC) { static zend_internal_function f; f.type = ZEND_OVERLOADED_FUNCTION; f.function_name = method; return (union _zend_function*)&f; } int test_method_call (char *method, INTERNAL_FUNCTION_PARAMETERS) { php_printf("%s called\n", method); RETURN_TRUE; }
#ifndef PHP_TEST_H #define PHP_TEST_H #include "php.h" extern zend_module_entry test_module_entry; #define phpext_test_ptr &test_module_entry PHP_MINIT_FUNCTION(test); ZEND_API zend_object_value test_objects_new(zend_class_entry * TSRMLS_DC); #endif #include "php.h" #include "php_test.h" static union _zend_function *test_method_get(zval *object, char *method, int method_len TSRMLS_DC); int test_method_call (char *method, INTERNAL_FUNCTION_PARAMETERS); ZEND_API zend_object_value test_objects_new(zend_class_entry *class_type TSRMLS_DC); PHP_MINIT_FUNCTION(test); zend_class_entry *test_class_entry; static zend_object_handlers test_object_handlers; zend_module_entry test_module_entry = { STANDARD_MODULE_HEADER, "test", NULL, PHP_MINIT(test), NULL, NULL, NULL, NULL, "0.1", STANDARD_MODULE_PROPERTIES }; #ifdef COMPILE_DL_RUBY ZEND_GET_MODULE(test) #endif PHP_MINIT_FUNCTION(test) { zend_class_entry _test_class_entry; INIT_CLASS_ENTRY(_test_class_entry, "test", NULL); _test_class_entry.create_object = test_objects_new; test_class_entry = zend_register_internal_class(&_test_class_entry TSRMLS_CC); memcpy(&test_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); test_object_handlers.call_method = test_method_call; test_object_handlers.get_method = test_method_get; } ZEND_API zend_object_value test_objects_new(zend_class_entry *class_type TSRMLS_DC) { zend_object_value retval; zend_object *intern; zval *tmp; intern = emalloc(sizeof(zend_object)); intern->ce = class_type; intern->in_get = 0; intern->in_set = 0; ALLOC_HASHTABLE(intern->properties); zend_hash_init(intern->properties, 0, NULL, ZVAL_PTR_DTOR, 0); zend_hash_copy( intern->properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); retval.handle = zend_objects_store_put(intern, NULL, NULL, NULL TSRMLS_CC); retval.handlers = &test_object_handlers; return retval; } static union _zend_function *test_method_get(zval *object, char *method, int method_len TSRMLS_DC) { static zend_internal_function f; f.type = ZEND_OVERLOADED_FUNCTION; f.function_name = method; return (union _zend_function*)&f; } int test_method_call (char *method, INTERNAL_FUNCTION_PARAMETERS) { php_printf("%s called\n", method); RETURN_TRUE; }