¿Cómo rastreo una “Excepción lanzada sin un marco de stack en Desconocido en la línea 0” en PHP?

Estoy trabajando en una base de código grande (heredada) en PHP, y el error Exception thrown without a stack frame in Unknown on line 0 ha comenzado a aparecer en la parte inferior de cada página. Entiendo lo que significa el error: se lanza una excepción a un lugar donde no se puede lanzar. Incluso he logrado rastrearlo un poco, está sucediendo durante el tiempo en que se convocan las funciones de apagado.

He puesto logging en todas las funciones que se registran con register_shutdown_function , y no está sucediendo en ninguna de esas funciones. Desafortunadamente, parece que no puedo obtener más información que esa; Sé cuál es la última función de apagado para que se llame con éxito, pero no tengo idea qué código se ejecuta entre eso y el punto donde ocurre el error. Ni siquiera sé qué parte de la maquinaria PHP está llamando a esa última función de apagado. Puede ser algo con el marco de trabajo de registro, o el marco de sesión, o cualquier cosa de media docena de cosas.

¿Alguien sabe cómo identificar dónde se produce el error?

Esto puede suceder en destructores y manejadores de excepciones que no tienen un marco de stack. Pero como el mensaje es muy útil, tu única opción es intentar usar echo para encontrar el error (y tal vez ob_end_flush() ). Puede ser que un destructor esté lanzando una excepción o llame a una función que arroje una excepción. Una vez que haya localizado la función de errores, agregue un bash … atrape la parte que arroja la excepción.

Tenga en cuenta que si su marco utiliza su propio manejo de errores, debe desactivar las advertencias y avisos en la configuración de PHP. Especialmente si tiene algo así como ErrorException , ya que convierte las advertencias en excepciones.

Este mensaje aparece cuando se produce una excepción dentro de su manejador de excepciones o su manejador de errores (y tal vez también en las funciones de apagado)

Deberías buscar estos métodos para ver si nada extraño aparece aquí.

Acabo de encontrar su pregunta después de experimentar el mismo error en una aplicación web implementada en un servidor Ubuntu 11.04, ejecutando PHP 5.3.5. Estoy de acuerdo con @Eisberg en que este problema parece ser un problema exclusivo de PHP 5.3, ya que el error no ha estado presente en versiones anteriores de PHP en otros entornos en los que se implementó mi aplicación.

Como menciona @jmz, también he utilizado un controlador de errores que convierte los errores en excepciones para una depuración más sencilla en mis servidores de almacenamiento intermedio.

Para descubrir qué causó este comportamiento misterioso, depuré la aplicación usando XDEBUG y mi IDE (Eclipse) y descubrí que una de mis bibliotecas intentó acceder y modificar la variable $_SESSION global, cuando no se establecieron datos de sesión. Envolver mi código en una statement de estado isset($_SESSION) hizo que el problema desapareciera.

La razón por la que la excepción no brotó completamente hasta el navegador, como han hecho otros errores al intentar acceder a variables no establecidas, es un completo misterio para mí, especialmente porque obtuve la configuración de error por debajo, pero tal vez alterando el establecer en error_reporting() habría hecho la diferencia.

Manejo de errores de configuración, para referencia:

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

Obtengo el mismo mensaje de error también. La cuota de la base de datos MySQL fue establecida por awardspace como 50mb. El uso de PHPmyAdmin para optimizar los archivos mostró un tamaño de 34 mb pero en cPanel el tamaño se mostró como 57mb. Cada vez que visito mi sitio web y se produce este mensaje de error, todo lo que tengo que hacer es iniciar sesión en el espacio de premios, elegir la base de datos, la administración y restablecer los permisos del archivo. Luego, el mensaje de error desaparece y mi sitio web vuelve a funcionar.

Estaba recibiendo este problema en PHPUnit . He agregado el código siguiente en la function tearDown y me ayuda a obtener el error real. Debería envolver el destructor dentro de un bloque try-catch, ya que el marco de la stack solo se pierde tan pronto como la excepción salga del destructor. Puede ser que esto también pueda ayudar a alguien más. Fuente

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