wamped.org

Heavier than it looks

1 note &

PHP: Hunting down the dreaded “Exception thrown without a stack frame in Unknown on line 0” message

Though the infamous exception mentioned in the title looks really bad, and initially seems hard to locate the root of the problem, there are actually only a few situations when this exception will be thrown. These are:

    * an exception is thrown within the exception handler
    * an exception is thrown during the php engine shutdown
    * an exception is thrown in an object’s destructor function

(I vaguely recall a situation when this exception was raised somehow in connection with __autoload and class_exists functions, but couldn’t reproduce it, so I’ll just omit that as a possible cause. If it ever floats back into my brain, I promise to share it.)

Here is a very simple piece of code for how to throw this exception:

<?php
	register_shutdown_function('custom_shutdown');
	echo "Hello, we are trying to create an ugly exception";
	exit;

	function custom_shutdown() { 
		throw new Exception("You'll never get me!");
	}
?>


Running the above snippet will give you a nice fat “PHP Fatal error:  Exception thrown without a stack frame in Unknown on line 0” in your error log. Notice how you’ve lost every piece of information from the original exception: message, stack, everything.

Ok, I hear you, we’re not interested in creating the exception but rather in finding the piece of code that throws the exception. Basically I already gave you the solution, you’ll have to look through the code in custom exception handlers, shutdown functions and class destructors.
Search for the following expressions within your php project:

  • "register_shutdown_function"
  • "set_exception_handler"
  • "function __destruct()"

So, sticking to the first example, if you manage to find something like “register_shutdown_function(‘custom_shutdown’);” in the code, you’ll have to find the custom_shutdown function and put the whole content of it into a try/catch block. The same goes for the other two possible locations. Using the first example (where we produced the exception), you’d need to modify the code like this:

<?php
	register_shutdown_function('custom_shutdown');
	echo "Hello, we are trying to create an ugly exception";
	exit;

	function custom_shutdown() {
		try { 
			throw new Exception("You'll never get me!");
		} catch (Exception $e) {
	            	error_log(get_class($e)." thrown within the shutdown handler. Message: ".$e->getMessage(). "  in " . $e->getFile() . " on line ".$e->getLine());
	            	error_log('Exception trace stack: ' . print_r($e->getTrace(),1));
    	    	}
	}
?>

If you run the above code, you’ll see “Exception thrown within the shutdown handler. Message: You’ll never get me!  in your_location/test.php on line 8” message, and a stack trace in your error log file. Much more informative than before, right?

Happy debugging!

Filed under php exception debugging

  1. wamped posted this