En informática , un seguimiento de pila (también llamado seguimiento de pila [1] o seguimiento de pila [2] ) es un informe de los marcos de pila activos en un momento determinado durante la ejecución de un programa . Cuando se ejecuta un programa, la memoria a menudo se asigna dinámicamente en dos lugares; la pila y el montón . La memoria se asigna continuamente en una pila pero no en un montón, por lo que refleja sus nombres. La pila también se refiere a una construcción de programación, por lo que para diferenciarla, esta pila se conoce como la pila en tiempo de ejecución del programa.. Técnicamente, una vez que se ha asignado un bloque de memoria en la pila, no se puede eliminar fácilmente, ya que puede haber otros bloques de memoria que se asignaron antes. Cada vez que se llama a una función en un programa, se asigna un bloque de memoria en la parte superior de la pila de tiempo de ejecución llamado registro de activación (o puntero de pila). En un nivel alto, un registro de activación asigna memoria para los parámetros de la función y las variables locales declaradas en la función.
Los programadores suelen utilizar el seguimiento de pila durante la depuración interactiva y post-mortem . Los usuarios finales pueden ver un seguimiento de la pila que se muestra como parte de un mensaje de error , que luego el usuario puede informar a un programador.
Un seguimiento de pila permite rastrear la secuencia de funciones anidadas llamadas, hasta el punto en el que se genera el seguimiento de pila. En un escenario post-mortem, esto se extiende hasta la función donde ocurrió la falla (pero no fue necesariamente causada). Las llamadas de hermanos no aparecen en un seguimiento de pila.
Ayuda de idioma
Muchos lenguajes de programación, incluidos Java y C # , tienen soporte integrado para recuperar el seguimiento de la pila actual a través de llamadas al sistema. C ++ no tiene soporte integrado para hacer esto, pero los usuarios de C ++ pueden recuperar seguimientos de pila con (por ejemplo) la biblioteca stacktrace . En JavaScript , las excepciones contienen una propiedad que contiene la pila desde el lugar donde se lanzó.stack
Pitón
Como ejemplo, el siguiente programa de Python contiene un error.
def a (): i = 0 j = b ( i ) volver jdef b ( z ): k = 5 si z == 0 : c () volver k + zdef c (): error ()un ()
La ejecución del programa con el intérprete estándar de Python produce el siguiente mensaje de error.
Traceback (última llamada más reciente): Archivo "tb.py" , línea 15 , en ódulo> a () Archivo "tb.py" , línea 3 , en a j = b ( i ) Archivo "tb.py" , línea 9 , en b c () Archivo "tb.py" , línea 13 , en c error () NameError : el nombre 'error' no está definido
El seguimiento de la pila muestra dónde ocurre el error, es decir, en la c
función. También muestra que la c
función fue llamada por b
, que fue llamada por a
, que a su vez fue llamada por el código en la línea 15 (la última línea) del programa. Los registros de activación para cada una de estas tres funciones se organizarían en una pila de modo que la a
función ocuparía la parte inferior de la pila y la c
función ocuparía la parte superior de la pila.
Java
En Java , los seguimientos de pila se pueden volcar manualmente con Thread.dumpStack()
[3] Tome la siguiente entrada:
public class Main { public static void main ( String args [] ) { demo (); } demo de vacío estático () { demo1 (); } demo1 vacío estático () { demo2 (); } demo2 vacío estático () { demo3 (); } demo3 vacío estático () { Hilo . dumpStack (); }}
La excepción enumera las funciones en orden descendente, por lo que la llamada más interna es la primera.
java . lang . Excepción : seguimiento de pila en java . lang . Hilo . dumpStack ( Thread . java : 1336 ) en Main . demo3 ( Main . java : 15 ) en Main . demo2 ( Main . java : 12 ) en Main . demo1 ( Main . java : 9 ) en Main . demo ( Main . java : 6 ) en Main . main ( Main . java : 3 )
C y C ++
Tanto C como C ++ no tienen soporte nativo para seguimientos de pila, pero las bibliotecas como glibc y boost contienen métodos que funcionan como ellos. [4] [5]
Por ejemplo, la función de glibcbacktrace()
devuelve una salida con la función del programa y la dirección de memoria.
. / a . out () [ 0x40067f ] . / a . out () [ 0x4006fe ] . / a . out () [ 0x40070a ] / lib / x86_64 - linux - gnu / libc . entonces .6 ( __libc_start_main + 0xf5 ) [ 0x7f7e60738f45 ] . / a . fuera () [ 0x400599 ]
Oxido
El óxido tiene dos tipos de errores. Las funciones que utilizan la macro de pánico son "irrecuperables" y abortan el programa por completo. Las funciones que devuelven a std::result::Result
son "recuperables" y se pueden manejar con elegancia. Sin embargo, los errores recuperables no pueden generar un seguimiento de la pila, ya que se agregan manualmente y no son el resultado de un error en tiempo de ejecución.
A partir de junio de 2021, Rust tiene soporte experimental para seguimientos de pila en errores irrecuperables. Rust admite la impresión en stderr cuando un hilo entra en pánico, pero debe habilitarse estableciendo la RUST_BACKTRACE
variable de entorno . [6]
Cuando están habilitados, estos retrocesos se ven similares a los de abajo, con la llamada más reciente primero.
el hilo ' main ' entró en pánico en ' execute_to_panic ' , main . rs : 3 stack backtrace : 0 : std :: sys :: imp :: backtrace :: tracing :: imp :: desenrollar_backtrace 1 : std :: panicking :: default_hook :: {{ cierre }} 2 : std :: pánico :: default_hook 3 : std :: pánico :: rust_panic_with_hook 4 : std :: pánico :: begin_panic 5 : futuros :: task_impl :: con 6 : futuros :: task_impl :: park.. .
Ver también
Referencias
- ^ "manual de libc: retrocesos" . gnu.org . Consultado el 8 de julio de 2014 .
- ^ "traceback: imprime o recupera un seguimiento de pila" . python.org . Consultado el 8 de julio de 2014 .
- ^ "Hilo (Java Platform SE 8)" . docs.oracle.com . Consultado el 15 de junio de 2021 .
- ^ "Backtraces (La biblioteca GNU C)" . www.gnu.org . Consultado el 15 de junio de 2021 .
- ^ "Introducción - 1.76.0" . www.boost.org . Consultado el 15 de junio de 2021 .
- ^ "std :: backtrace - Óxido" . doc.rust-lang.org . Consultado el 15 de junio de 2021 .