En informática , un rastreo de pila (también llamado rastreo de pila [ 1 ] o rastreo de pila [ 2 ] ) es un informe de los marcos de pila activos en un punto determinado durante la ejecución de un programa . Cuando se ejecuta un programa, la memoria se asigna dinámicamente en dos lugares: la pila y el montón . La memoria se asigna continuamente en la pila, pero no en el montón. La pila también se refiere a una construcción de programación; por lo tanto, para diferenciarla, esta pila se denomina pila de llamadas a funciones 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 hayan asignado después. Cada vez que se llama a una función en un programa, se asigna un bloque de memoria llamado registro de activación en la parte superior de la pila de llamadas. Generalmente, el registro de activación almacena los argumentos y las variables locales de la función. Lo que contiene exactamente y cómo está organizado viene determinado por la convención de llamada .
Los programadores suelen utilizar el rastreo de pila durante la depuración interactiva y post mortem . Los usuarios finales pueden ver el rastreo de pila como parte de un mensaje de error , que luego pueden comunicar a un programador.
Un rastreo de pila permite seguir la secuencia de funciones anidadas llamadas hasta el punto donde se genera. En un análisis posterior al fallo, esto se extiende hasta la función donde ocurrió (aunque no necesariamente fue la causa). Las llamadas a funciones hermanas no aparecen en un rastreo de pila.
Soporte de idiomas
Muchos lenguajes de programación, incluidos Java [ 3 ] y C# , [ 4 ] tienen soporte incorporado para recuperar el rastro de pila actual a través de llamadas al sistema. Antes de std::stacktraceque se agregara en la biblioteca estándar como un contenedor para std::stacktrace_entry, pre -C++23 no tiene soporte incorporado para hacer esto, pero los usuarios de C++ pueden recuperar rastros de pila con (por ejemplo) la biblioteca stacktrace . En JavaScript , las excepciones tienen una propiedad que contiene la pila desde el lugar donde se lanzó.stack
Pitón
Como ejemplo, el siguiente programa Python contiene un error.
def a () -> int :i : int = 0j : int = b ( i )devolver jdef b ( z : int ) -> int :k : int = 5si z == 0 :c ()devolver k + zdef c () -> Ninguno :error ()Si __name__ == "__main__" :a ()Al ejecutar el programa con el intérprete estándar de Python, se produce el siguiente mensaje de error.
Rastreo de la pila (llamada más reciente): Archivo "file.py" , línea 16 , en <module> a () Archivo "file.py" , línea 3 , en a j = b ( i ) Archivo "file.py" , línea 9 , en b c () Archivo "file.py" , línea 13 , en c error () NameError : el nombre 'error' no está definidoEl rastreo de la pila muestra dónde ocurre el error, concretamente en la cfunción. También muestra que la cfunción fue llamada por b, que aa su vez fue llamada por , que fue llamada por el código de la línea 16 (la última línea) del programa. Los registros de activación de cada una de estas tres funciones se organizarían en una pila de tal forma que la afunción ocuparía la parte inferior de la pila y la cfunción ocuparía la parte superior.
Java
En Java , los rastreos de pila se pueden volcar manualmente con java.lang.Thread::dumpStack()[ 5 ] Tome la siguiente entrada:
clase pública Main {static void demo () {demo1 ();}static void demo1 () {demo2 ();}static void demo2 () {demo3 ();}static void demo3 () {Hilo.dumpStack ( ) ;}public static void main ( String args [] ) {demostración ();}}La excepción enumera las funciones en orden descendente, por lo que la llamada más interna aparece primero.
java.lang.Exception : Seguimiento de pila en java.lang.Thread.dumpStack ( Thread.java:1336 ) en Main.demo3 ( Main.java:15 ) en Main.demo2 ( Main.java:11 ) en Main.demo1 ( Main.java:7 ) en Main.demo ( Main.java:3 ) en Main.main ( Main.java:19 )Java también permite recuperar el rastro de pila actual usando java.lang.Thread::getStackTrace(), o mostrar el rastro de pila en un error usando java.lang.Throwable::printStackTrace(). Un rastro de pila en Java se representa como java.lang.StackTraceElement[], un array. [ 6 ]
C y C++
C no tiene soporte nativo para obtener rastreos de pila, pero bibliotecas como glibc proporcionan esta funcionalidad. [ 7 ]
En C y C++, algunas optimizaciones del compilador pueden interferir con la información de la pila de llamadas que se puede recuperar en tiempo de ejecución. Por ejemplo, la inserción de funciones en línea puede provocar la pérdida de marcos de pila, las optimizaciones de llamadas recursivas pueden reemplazar un marco de pila por otro, y la eliminación de punteros de marco puede impedir que las herramientas de análisis de la pila de llamadas interpreten correctamente su contenido. [ 7 ]
Por ejemplo, la función de glibc backtrace()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 . so .6 ( __libc_start_main + 0xf5 ) [ 0x7f7e60738f45 ] . / a . out () [ 0x400599 ]Antes de C++23 , no existían mecanismos en C++ para obtener trazas de pila, pero las bibliotecas de terceros como Boost.Stacktrace ofrecían trazas de pila. [ 8 ] C++23 agregó trazas de pila con std::stacktracey std::stacktrace_entry[ 9 ] Las trazas de pila se pueden volcar manualmente imprimiendo el valor devuelto por la función miembro estática std::stacktrace::current(): [ 10 ]
importar std ;usando std :: stacktrace ;void bar () { std :: println ( "Rastreo de pila desde bar(): \n {}" , stacktrace :: current ()); }void foo () { bar (); }int main () { foo (); }DO#
Óxido
Rust tiene dos tipos de errores. Las funciones que usan la macro panic son "irrecuperables" y el hilo actual se contaminará experimentando un desenrollado de pila. Las funciones que devuelven un valor std::result::Resultson "recuperables" y se pueden manejar de forma elegante. [ 12 ] Sin embargo, los errores recuperables no pueden generar un rastreo de 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 cuenta con soporte experimental para rastreos de pila en errores irrecuperables. Rust admite la impresión en stderr cuando un hilo entra en pánico, pero debe habilitarse configurando la RUST_BACKTRACEvariable de entorno . [ 13 ]
Cuando están habilitadas, estas trazas de pila se ven similares a las que se muestran a continuación, con la llamada más reciente primero.
El hilo ' main ' entró en pánico en ' execute_to_panic ' , main.rs:3 rastreo de pila : 0 : std :: sys :: imp :: backtrace :: tracing :: imp :: unwind_backtrace 1 : std :: panicking :: default_hook :: {{ closure }} 2 : std :: panicking :: default_hook 3 : std :: panicking :: rust_panic_with_hook 4 : std :: panicking :: begin_panic 5 : futures :: task_impl :: with 6 : futures :: task_impl :: park ...Véase también
Referencias
- ↑ "Manual de libc: rastreos de pila" . gnu.org . Consultado el 8 de julio de 2014 .
- ↑ "traceback — Imprime o recupera un rastreo de pila" . python.org . Consultado el 8 de julio de 2014 .
- ↑ "Hilo (Java SE 16 y JDK 16)" . Especificación de la API de la plataforma Java Standard Edition y Java Development Kit versión 16. 4 de marzo de 2021. Consultado el 4 de julio de 2021 .
- ↑ "Propiedad Environment.StackTrace (Sistema)" . Microsoft Docs . 2021-05-07 . Consultado el 2021-07-04 .
- ↑ "Hilo (Plataforma Java SE 8)" . docs.oracle.com . Consultado el 15 de junio de 2021 .
- ↑ Oracle Corporation. "Clase StackTraceElement" . docs.oracle.com . Oracle Corporation . Consultado el 1 de mayo de 2026 .
- 1 2 "Backtraces (La biblioteca C de GNU)" . www.gnu.org . Consultado el 15 de junio de 2021 .
- ↑ "Primeros pasos - 1.76.0" . www.boost.org . Consultado el 15 de junio de 2021 .
- ↑ cppreference.com. "Encabezado de la biblioteca estándar <stacktrace> (C++23)" . cppreference.com . cppreference.com . Consultado el 1 de mayo de 2026 .
- ↑ "Borrador de trabajo, estándar para el lenguaje de programación C++" (PDF) . open-std.org . ISO/IEC. 23 de octubre de 2021. pág. 766.
- ↑ Microsoft Learn. "Clase StackTrace" . Microsoft Learn . Microsoft Learn . Consultado el 1 de mayo de 2026 .
- ↑ "Desenrollado de Rustonomicon - Rust" . doc.rust-lang.org .
- ↑ "std::backtrace - Rust" . doc.rust-lang.org . Consultado el 15 de junio de 2021 .
- Depuración