Edit report at http://bugs.php.net/bug.php?id=54157&edit=1

 ID:                 54157
 Comment by:         nicolas dot grekas+php at gmail dot com
 Reported by:        tstarling at wikimedia dot org
 Summary:            Destruction of some global variables before session
                     write handler callback
 Status:             Wont fix
 Type:               Bug
 Package:            Scripting Engine problem
 Operating System:   Linux
 PHP Version:        5.3SVN-2011-03-03 (SVN)
 Block user comment: N
 Private report:     N

 New Comment:

If you add this to your code, it works around the problem, while still
closing the session as late as possible I think :



<?php

register_shutdown_function('shutdown_session');

function shutdown_session()
{register_shutdown_function('session_write_close');}

?>


Previous Comments:
------------------------------------------------------------------------
[2011-03-04 10:19:49] johan...@php.net

This is a hen and egg problem. First issue which comes to mind is: What
happens if a destructor wants to log it's state or such in the session?



We have tuned the order multiple times and the current behaviour is the
best of the bad choices we have.

------------------------------------------------------------------------
[2011-03-04 01:29:20] tstarling at wikimedia dot org

Here's another argument in favour of adding a new hook to
php_request_shutdown(): the point of session_set_save_handler() is to
allow userspace code to implement alternative methods of session
storage. Writing to alternate storage will typically involve calling
some other PHP module. But how can we safely call other PHP modules when
half of them will have had their RSHUTDOWN functions called? There is
the potential for subtle bugs dependent on module load order: dangling
pointers, memory corruption, etc.

------------------------------------------------------------------------
[2011-03-04 00:54:47] tstarling at wikimedia dot org

Description:
------------
The request function of the session module calls custom session save
handlers. Because modules are shut down after zend_call_destructors() is
called, this exposes the weird and apparently broken behaviour of
zend_call_destructors() to the user space. 



Its effect is to delete all global variables with a reference count of
1, but only if they hold an object. Global variables which are
referenced from anywhere, including other global variables, are not
deleted. 



Ideally, I would like session save handlers to have reliable access to
global variables. That probably means calling them before the
user-defined __destruct() functions, say with an extra hook into
php_request_shutdown(). 



Failing that, I would like the behaviour to be consistent and
predictable, so that we don't end up with strange regressions like the
one observed here:



http://www.mediawiki.org/wiki/Special:Code/MediaWiki/83140#c14601

Test script:
---------------
<?php



function noop() {}

function save() {

        debug_zval_dump( $GLOBALS['a'] );

        debug_zval_dump( $GLOBALS['b'] );

        debug_zval_dump( $GLOBALS['c'] );

}

class Foo {}



$a = new Foo;

$b = new Foo;

$c =& $b;



session_set_save_handler( 'noop', 'noop', 'noop', 'save', 'noop', 'noop'
);

session_start();





Expected result:
----------------
object(Foo)#1 (0) refcount(2){

}

object(Foo)#2 (0) refcount(1){

}

object(Foo)#2 (0) refcount(1){

}



Actual result:
--------------
Notice:  Undefined index: a in
/home/tstarling/src/php/stuff/weird-shutdown_destructors.php on line 5

NULL refcount(1)

object(Foo)#2 (0) refcount(1){

}

object(Foo)#2 (0) refcount(1){

}




------------------------------------------------------------------------



-- 
Edit this bug report at http://bugs.php.net/bug.php?id=54157&edit=1

Reply via email to