debug_backtrace () de la función de apagado registrada en PHP

4 minutos de lectura

avatar de usuario
Dan Lugg

Mientras buscaba una respuesta a esta pregunta, descubrí que debug_backtrace() no rastrea más allá de la función registrada para register_shutdown_function()cuando se llama desde dentro de ella.

Esto fue mencionado en este comentario por register_shutdown_function() en los documentos de PHP, indicando:

Puede tener la idea de llamar a debug_backtrace o debug_print_backtrace desde dentro de una función de apagado, para rastrear dónde ocurrió un error fatal. Desafortunadamente, estas funciones no funcionarán dentro de una función de apagado.

Explicado con un poco más de detalle, los comentarios sobre este estado de respuesta:

no funciona La función de apagado se produce después de que la pila se haya desenrollado. No hay información de pila para volcar.

¿Hay alguna forma de eludir esto, obligando a PHP a mantener el seguimiento de la pila hasta que el proceso haya terminado por completo, o deberíamos aceptarlo como un hecho debido a las funciones internas de PHP?

avatar de usuario
powtac

Esto es un muy caro solución. nunca usé register_tick_function() o tick y no estoy seguro si funciona como se esperaba.

declare(ticks=1);

function tick_handler() {
    global $backtrace;
    $backtrace = debug_backtrace();
}
register_tick_function('tick_handler');



function shutdown() {
    global $backtrace;
    // do check if $backtrace contains a fatal error...
    var_dump($backtrace);
}
register_shutdown_function('shutdown');

  • Gracias @powtac – Gran solución, sin embargo, no funcionó. Ciertamente veo a dónde ibas con eso. Lo engañé un poco, pero sin éxito todavía.

    – Dan Lug

    30 de agosto de 2011 a las 13:50

  • eso es inteligente seguro. no sabía sobre la función de tic

    –David Mann

    15 de julio de 2016 a las 1:05

  • Estaba buscando lo mismo y encontré esto: gist.github.com/rmbl/5780995. Sin embargo, no lo intenté. Nota declare(ticks=1); al final

    – Karmalakas

    24 de enero de 2018 a las 13:23


  • necesitas el declare(ticks=1) declaración en cada archivo de su proyecto para que esto funcione

    –Lucas Bustamante

    14 oct 2021 a las 17:53

¿Hay alguna forma de eludir esto, obligando a PHP a mantener el seguimiento de la pila?

Eso no tiene sentido, cuando se invoca la función registrada, todas sus funciones definidas han regresado o se han borrado de la pila.

Si necesita saber dónde salió su código, entonces necesita instrumentar su código.

  • Gracias @symcbean: dado que todas las demás funciones en una ejecución dada han regresado, y hemos vuelto a subir al alcance global, por supuesto; sin embargo, la parte donde las llamadas a funciones incompletas se borran de la pila (dado exit se llama a una profundidad arbitraria de llamadas anidadas) es lo que encuentro desafortunado, y no sin sentido. nunca uso exit para el control de ejecución, favoreciendo las excepciones para manejar mi lógica de error; esto fue más una investigación académica, en lugar del mundo real. Sin embargo, tiene sentido en mi opinión que la pila debe conservarse hasta que el proceso se elimine por completo.

    – Dan Lug

    30 de agosto de 2011 a las 13:55

  • Entonces, ¿qué sucedería cuando regresara su función de apagado registrada?

    – symcbean

    30 de agosto de 2011 a las 15:57

  • Toque, señor; Solo pensé que PHP lo haría (debería) mantener la pila al final del script, verificar los controladores, ejecutar los controladores, lavar, enjuagar y repetir hasta que la cola esté vacía, y después finalizar la ejecución.

    – Dan Lug

    11 de septiembre de 2011 a las 22:15


  • Puedes usar error_get_last para encontrar dónde se generó el error, pero no le dará la pila.

    – Pablo

    20 de enero de 2012 a las 5:50

En XDebug extensión, hay una xdebug_get_function_stack() función.

Este funciona de manera similar al interno de PHP. debug_backtrace()pero mantiene el seguimiento incluso en el controlador de apagado.

Sin embargo, no obtendrá el punto de salida exacto, solo la última función ejecutada antes de que ocurriera el apagado (activado por die()/exit() llamada o error).

Por supuesto, esto solo es adecuado para el entorno de desarrollo.

  • peculiaridad: no funciona para excepciones no detectadas… a menos que se haya configurado un controlador de excepciones predeterminado con set_exception_handler

    – Brad Kent

    12 de septiembre de 2017 a las 3:40

  • peculiaridad #2: xdebug_get_function_stack() comienza con la función de apagado si hubo un error de análisis

    – Brad Kent

    12 de septiembre de 2017 a las 16:14

Según mi experiencia, la función de apagado comienza con una pila limpia y no tiene acceso a la pila “original” (ya que ya no existe en ese punto).

Desafortunadamente, no hay forma de guardar esa pila original.

Dentro de su función de apagado registrada, puede obtener un seguimiento por error_get_last función. Funciona para mí en PHP7.

  • Esto solo obtiene el archivo y la línea donde ocurrió el error, no el seguimiento completo.

    – Sinus the Tentacular

    12 de marzo de 2019 a las 19:16

  • Esto solo obtiene el archivo y la línea donde ocurrió el error, no el seguimiento completo.

    – Sinus the Tentacular

    12 de marzo de 2019 a las 19:16

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad