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

Reply via email to