If a module adds anything to $_SESSION on hook_exit, it results in a fatal error:
PHP Fatal error: session_start(): Failed to initialize storage module
The error is supressed in the browser since drupal_exit is called after the Location header is sent, but it shows up in the error log.
Attached is a module to replicate the problem and a potential fix.
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | base-system-session-758730-19.patch | 2.98 KB | moymilo |
| #12 | session.patch | 3.55 KB | mfb |
| #9 | session_test_module_hook_exit.patch | 730 bytes | msonnabaum |
| #5 | session_destroy-d6.patch | 1.56 KB | neclimdul |
| #3 | session_destroy.patch | 2.41 KB | mfb |
Comments
Comment #1
neclimdulsubscribe
Comment #2
mfbBy the way this is related to a Drupal 6 issue: #500680: Fatal error on logout
Another way to work around the "failed to initialize storage module" PHP bug might be to reset the session handlers after destroying the session? i.e.
session_set_save_handler('_drupal_session_open', '_drupal_session_close', '_drupal_session_read', '_drupal_session_write', '_drupal_session_destroy', '_drupal_session_garbage_collection');This is assuming we do want to allow the session to be saved after logout, which perhaps some contrib module needs to do.The suggested fix of emptying the session after logout might be too brittle, what if some other path is used to destroy the session?
Comment #3
mfbHere's the alternate potential fix. We make a new wrapper function, drupal_session_destroy() to workaround http://bugs.php.net/bug.php?id=32330
This allows contrib modules to save stuff to the session even after logout.
Comment #4
msonnabaum commentedI like this approach much better. Works well in my testing.
Btw, I ran into this initially using Pressflow and ubercart. It's a pretty rare scenario, but uc_store can end up writing to the session in hook_exit.
More details on the launchpad thread for those interested: https://bugs.launchpad.net/pressflow/+bug/513117
Comment #5
neclimduld6 port for pressflow et al.
Comment #6
alexpottJust used the patch in #5 on a pressflow site using memcache and I needed to add the new function drupal_session_destroy() to the memcache-session.inc in order to get it to. Once done it works a treat. Thanks.
Comment #7
c960657 commentedThis problem was also discussed in #477944: Fix and streamline page cache and session handling, though apparently it wasn't fixed completely back then (or the problem has been reintroduced in the meantime).
Would it be sufficient to move the session_set_save_handler() call from drupal_session_initialize() to drupal_session_start()?
Comment #8
mfbI think that might work, and would be a nicer fix. Unfortunately I can't test right now as I since upgraded the site where I reproduced this to PHP 5.3 (which doesn't suffer from the PHP bug).
The problem was mostly fixed by setting $_SESSION to an empty array, aside from this edge case.
Comment #9
msonnabaum commentedHere's a patch for the session_test module to expose this bug in simpletest.
Comment #11
gpk commentedRelated: #592482: Regression: data stored in $_SESSION in hook_boot() or hook_exit() during a cached page response is lost.
Comment #12
mfbHere's a shorter patch as suggested in #7 and a test that may trigger the fatal error (depending on server environment)
Comment #13
thedavidmeister commentedPatch in #12 no longer applies:
error: session.inc: No such file or directory
error: simpletest/tests/session.test: No such file or directory
Comment #14
dcam commentedMy guess is that this error doesn't occur in 8.x, but that should probably checked. Isn't session handling done by Symfony?
Regardless, #12 needs to be rerolled for 7.x.
Comment #15
moymilo commentedReroll #12 for 7.x.
Comment #17
moymilo commentedComment #19
moymilo commentedComment #20
moymilo commentedComment #22
moymilo commented