Как отследить «Исключение, исключенное без фрейма стека в Unknown on line 0» в PHP?

Я работаю над большой (унаследованной) кодовой базой в PHP, а ошибка Exception thrown without a stack frame in Unknown on line 0 , начала отображаться внизу каждой страницы. Я понимаю, что означает ошибка: исключение получает брошенное место, которое невозможно выбросить. Мне даже удалось немного отследить его – это происходит во время выключения функций выключения.

Я зарегистрировал все функции, которые регистрируются в register_shutdown_function , и это не происходит ни в одном из них. К сожалению, я не могу получить больше информации, чем это; Я знаю, какая последняя функция выключения для вызова вызвана, но я понятия не имею, какой код выполняется между этим и точкой, где происходит ошибка. Я даже не знаю, какая часть механизма PHP вызывает эту последнюю функцию отключения. Это может быть что-то с фреймворком протоколирования или средой сеанса или с чем-то вроде полдюжины вещей.

Кто-нибудь знает, как определить, где происходит ошибка?

Это может произойти в деструкторах и обработчиках исключений, которые не имеют фрейма стека. Но поскольку сообщение настолько полезно, ваш единственный вариант – попытаться использовать echo чтобы найти ошибку (и, возможно, ob_end_flush() ). Возможно, деструктор бросает исключение или вызывает функцию, которая генерирует исключение. После того, как вы найдете функцию багги, добавьте попытку … поймать часть метаданных исключения.

Обратите внимание: если ваша инфраструктура использует собственную обработку ошибок, вы должны отключить предупреждения и уведомления в конфигурации PHP. Особенно, если у вас есть что-то вроде ErrorException , поскольку он превращает предупреждения в исключения.

Это сообщение появляется, когда исключение, созданное в вашем обработчике исключений или обработчике ошибок (и, возможно, также в функциях выключения)

Вы должны искать методы тезисов, видите ли здесь что-то странное.

Просто нашел ваш вопрос после того, как вы испытали ту же ошибку в веб-приложении, развернутом на сервере Ubuntu 11.04, с запуском PHP 5.3.5. Я согласен с @ Эйсбергом в том, что эта проблема, по-видимому, проблема с версией PHP 5.3 исключительно, поскольку ошибка не присутствовала в предыдущих версиях PHP в других средах, где мое приложение было развернуто.

Как упоминает @jmz, я также использовал обработчик ошибок, который превращает ошибки в исключения для более легкой отладки на моих промежуточных серверах.

Чтобы выяснить, что вызвало это таинственное поведение, я отлаживал приложение с помощью XDEBUG & my IDE (Eclipse) и выяснил, что одна из моих библиотек пыталась получить доступ и изменить глобальную переменную $_SESSION , когда не были установлены данные сеанса. Приобрести мой код в if-statement, проверяющем isset($_SESSION) проблема исчезла.

Почему исключение полностью не полностью перекрыло браузер, поскольку другие ошибки, возникающие при попытке доступа к не заданным переменным, являются для меня полной загадкой, тем более, что я получил ниже установленных параметров ошибок, но, возможно, изменил установка в error_reporting() имела бы значение.

Параметры обработки ошибок для справки:

 error_reporting(E_ALL | E_STRICT); ini_set("display_errors", 1); ini_set("html_errors", 1); 

Я получаю тоже сообщение об ошибке. Квота базы данных MySQL была установлена ​​наградным пространством как 50 МБ. Использование PHPmyAdmin для оптимизации файлов показало размер 34 мб, но в cPanel размер был указан как 57 МБ. Каждый раз, когда я нахожусь на своем веб-сайте, и эта ошибка возникла, все, что мне нужно сделать, это войти в систему наград, выбрать базу данных, управлять и сбросить разрешения на доступ к файлам. Тогда ошибка msg уходит, и мой веб-сайт возвращается обратно.

Я получил эту проблему в PHPUnit . Я добавил ниже код в function tearDown и помогает мне получить фактическую ошибку. Вы должны обернуть деструктор внутри блока try-catch, так как стековый фрейм только теряется, как только исключение выходит за пределы деструктора. Возможно, это тоже поможет кому-то другому. Источник

 function __destruct() { try { /* your code */ } catch(Exception $e) { echo $e->__toString(); } }