Hey, On Wed, 26 Nov 2003, Andi Gutmans wrote:
> Now that we're at a very advanced stage and the code freeze is coming up, I > think it'd be a good idea to start running some PHP 4 applications on PHP 5 > and see how easy things go. I'm sure we'll bump into some issues and many > of them might be solvable (using the already existing compatibility mode > for object cloning or by other means). There is one major problem that I see at this moment, and that is the problem with shutdown order and destructors. Problem 1: extension=mysql.so <?php class foo { private $c; function __construct() { $this->c = mysql_connect(); } function __destruct() { mysql_close($this->c); } } $f = new foo(); ?> This little script will give you a nice unresolved symbol when doing the mysql_close as the extensions are unloaded before the dtors run. Problem 2: The following script: <?php class A { public function __destruct() { echo "destructor!\n"; } } $obj = new A(); echo "I'm alive!\n"; ?> crashes Xdebug. While I thought it was *my* bug, it turned out to have the same cause as problem 1: the dtor is run after the GET/POST/COOKIE var tables are destroyed. (Xdebug tries to check some things in there on every function call). It's not only this, see problem 3. 788 zend_hash_find(PG(http_globals)[TRACK_VARS_GET]->value.ht, "XDEBUG_SESSION_START", sizeof("XDEBUG_SESSION_START"), (void **) &dummy) == SUCCESS (gdb) bt #0 0x0826325d in _zend_is_inconsistent (ht=0x5a5a5a5a, file=0x8417660 "/dat/dev/php/php-5.0dev/Zend/zend_hash.c", line=841) at /dat/dev/php/php-5.0dev/Zend/zend_hash.c:53 #1 0x082656f1 in zend_hash_find (ht=0x5a5a5a5a, arKey=0x406446bd "XDEBUG_SESSION_START", nKeyLength=21, pData=0xbfffe70c) at /dat/dev/php/php-5.0dev/Zend/zend_hash.c:841 #2 0x406325dd in xdebug_execute (op_array=0x405f9000) at /dat/dev/php/xdebug/xdebug.c:788 #3 0x08252cd3 in zend_call_function (fci=0xbfffec20, fci_cache=0x0) at /dat/dev/php/php-5.0dev/Zend/zend_execute_API.c:737 (gdb) frame 3 #3 0x08252cd3 in zend_call_function (fci=0xbfffec20, fci_cache=0x0) at /dat/dev/php/php-5.0dev/Zend/zend_execute_API.c:737 737 zend_execute(EG(active_op_array) TSRMLS_CC); (gdb) print *executor_globals.active_op_array $2 = {type = 2 '\002', function_name = 0x405f5608 "__destruct", scope = 0x405f7518, fn_flags = 16640, prototype = 0x0, num_args = 0, arg_info = 0x0, pass_rest_by_reference = 0 '\0', refcount = 0x405f792c, opcodes = 0x405f7968, last = 5, size = 5, T = 0, brk_cont_array = 0x0, last_brk_cont = 0, current_brk_cont = 4294967295, static_variables = 0x0, start_op = 0x0, backpatch_count = 0, return_reference = 0 '\0', done_pass_two = 1 '\001', uses_this = 0 '\0', filename = 0x405f5d8c "/dat/dev/php/xdebug/tests/bug00001.php", line_start = 3, line_end = 5, doc_comment = 0x0, doc_comment_len = 0, reserved = {0x0, 0x1, 0x8414a60, 0x923}} Problem 3: All extension globals are also destroyed before destructors run: 0x40631ac0 in add_stack_frame (zdata=0xbfffeb80, op_array=0x405f9000, type=0) at /dat/dev/php/xdebug/xdebug.c:684 684 xdebug_llist_insert_next(XG(stack), XDEBUG_LLIST_TAIL(XG(stack)), tmp); (gdb) bt #0 0x40631ac0 in add_stack_frame (zdata=0xbfffeb80, op_array=0x405f9000, type=0) at /dat/dev/php/xdebug/xdebug.c:684 #1 0x40632040 in xdebug_execute (op_array=0x405f9000) at /dat/dev/php/xdebug/xdebug.c:830 #2 0x08252cd3 in zend_call_function (fci=0xbfffec20, fci_cache=0x0) at /dat/dev/php/php-5.0dev/Zend/zend_execute_API.c:737 (gdb) print xdebug_globals.stack $2 = (xdebug_llist *) 0x0 (this variable is initialized in MINIT and destroyed in MSHUTDOWN). Parts of a chat with Zeev about this: 12:11 <@Derick> the hook you added "exec_finished" didn't solve my problem 12:11 <@Derick> because destructors are still called AFTER RSHUTDOWN :( 12:11 <@Zeev> they're not supposed to 12:11 <@Zeev> but I didnt do anything beyond exec_finished 12:11 <@Zeev> that is, nothing uses it yet 12:11 <@Derick> so what's the point of it ? :) 12:11 <@Zeev> the point is that it solves the problem 12:11 <@Zeev> once things start using it :) 12:12 <@Zeev> I can barely type 12:12 <@Zeev> my fingers are on fire 12:12 <@Derick> well, then the ZE needs to be modified to use it ;) 12:12 <@Derick> Zeev: peppers? 12:12 <@Zeev> derick the engine isnt supposed to use it 12:12 <@Derick> heh 12:12 <@Zeev> it simply has to call destructors after exec_finished 12:12 <@Zeev> but before rshutdown 12:12 <@Derick> yes 12:13 <@Zeev> but we cant do that before modules like the session module implement exec_finished 12:13 <@Derick> doesn't that need an engine mod then? 12:13 <@Derick> Zeev: ah ha 12:13 <@Zeev> because they're the reason destructors are called after rshutdown to begin with 12:13 <@Zeev> and yeah 12:13 <@Derick> Zeev: the problem is that if you mod session, the stuff needs to work first ... it's a chicken and egg problemm Related test case: 14:46 <@Derick> ZE2 accessing globals from destructor in shutdown [tests/classes/destructor_and_globals.phpt] 14:46 <@Derick> Andi_: thats the one I told you about a couple of days ago btw regards, Derick -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: http://www.php.net/unsub.php