php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52890 Exception not caught sometimes
Submitted: 2010-09-20 07:28 UTC Modified: 2010-09-28 10:26 UTC
From: j dot henge-ernst at interexa dot de Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 5.3.3 OS: Linux
Private report: No CVE-ID: None
 [2010-09-20 07:28 UTC] j dot henge-ernst at interexa dot de
Description:
------------
An Exception thrown is not caught by the corresponding catch block, instead the global exception handler is invoked. That only happens on one page during a long selenium test case. The bug is reproduceable with the selenium test script, but stripping the code to a small example does not result in an error. Will will add the stripped version of the code which does not fail, but show the code.

The System is a 64bit Zend Server 5.3 CE on CentOS 5.5. The same code on a Zend Server 5.2 CE does not have this problem. The problem also occurred in PHP 5.3.2


In the example script $defer should be set to true but instead of catching the excepetion in that block the global exception handler is called.

A fix for this is currently to use bofre the throw:
if (version_compare(PHP_VERSION, '5.3.0', '>=') && version_compare(PHP_VERSION, '5.3.3', '<=')) {
   set_exception_handler(create_function('$exception', 'return $exception instanceof iwat_ui_controller_ObjectSaveDeferredException ? true : userExceptionHandler($exception);'));
}
as the application behaves as expected, but that bug still exists. Disabling all Zend modules has no effect

Test script:
---------------
try {
    doSave();
} catch (iwat_ui_controller_ObjectSaveDeferredException $e) {
    $defer = true;
} catch (IWATException $e) {
}

function doSave() {
    throw new iwat_ui_controller_ObjectSaveDeferredException();
}


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-24 13:26 UTC] j dot henge-ernst at interexa dot de
We have tracked down the problem further using the Zend Code Tracer. It shows that before the throw is executed several objects are freed and there __destruct are called. After that the Execution stack seems to be corrupt and the Exception is not caught on the expected place.
Improving the testscript and adopting these experience still don't yield that problem. It seems that it only happens if the garbage collection? is run at the same time. For one executing path the exception works, but for another execution path it yields that error because additional objects are created.

In the __destruct we free additional references to other object so we do not have a memory problem in PHP 5.2.x

The __destruct now looks like and fixes the problem:

public function __destruct(){
        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
            return;
        }
        $this->_invalidateFieldChanges();
        $this->_objects = null;
        $this->_data = null;
        $this->_getfcache = null;
}

Url to the code traces:
http://entw.mainz.interexa.de/entw/hernst/phpbuild/phpbug52890-zend-code-trace-zsf.zip (15MB)
File trace-0-15823-1-20100924.zsf has that error, file trace-0-16180-1-20100924.zsf works as expected.
File trace-0-29017-1-20100924.zsf also does not catch an exception but is simpler and has less references to other objects.

I will also provide the xml files of the trace if the export works in the Zend Server.
 [2010-09-27 16:09 UTC] fa@php.net
-Status: Open +Status: Feedback
 [2010-09-27 16:09 UTC] fa@php.net
Please try to reproduce with PHP 5.3.3 from http://www.php.net/downloads.php 
instead of Zend Server or file a bug report with Zend.
 [2010-09-28 03:47 UTC] wakamonka747 at hotmail dot com
I'm experiencing the same in PHP 5.3.3 under Windows XP SP3, running as an apache 2.2.9 module.

An exception is thrown but is only caught by the outer most catch block.

i.e:

try {
   try {
     throw new Exception('foo');
   }
   catch(Exception $e) {
//Execution should follow here
   }  
}
catch(Exception $e) {
//Execution follows here
}

Although in my case there's no __destruct method implied
 [2010-09-28 03:49 UTC] wakamonka747 at hotmail dot com
Forgot to mention that I checked this behaviour with xdebug. You actually see how it just skips there.
 [2010-09-28 10:10 UTC] j dot henge-ernst at interexa dot de
-Status: Feedback +Status: Open
 [2010-09-28 10:10 UTC] j dot henge-ernst at interexa dot de
Happend with php 5.2.2 from Zend Server, happens with php 5.3.3 from php.net and from Zend Server 5.0.3 and with snapshot 5.3-201009280630 from php.net

configure was:
'./configure' '--with-libdir=lib64' '--prefix=/usr/local/php.net/5.3-201009280630' '--with-mysql' '--enable-zip' '--enable-pcntl' '--with-gd' '--with-apxs2' '--with-freetype-dir=yes' '--enable-gd-native-ttf' '--enable-mbstring' '--enable-calendar' '--enable-pcntl' '--with-oci8=instantclient,/interexa/lib64/oracle/instantclient_11_2' '--with-config-file-path=/usr/local/zend/etc'
 [2010-09-28 10:27 UTC] j dot henge-ernst at interexa dot de
-Status: Open +Status: Closed
 [2010-09-28 10:27 UTC] j dot henge-ernst at interexa dot de
Sorry have to correct me, with snapshot 5.3-201009280630 the problem no longer occurs. Might be fixed with bug #52361 which hadn't made it into 5.3.3
 [2010-10-07 03:17 UTC] wakamonka747 at hotmail dot com
Patched 5.3.3 source with bug #52361 fix code. Seems to work ok now.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 09:01:30 2024 UTC