gdb - usar - Lista de todas las llamadas a funciones realizadas en una aplicación
ok google voy a necesitar el paraguas mañana (4)
¿Cómo podemos enumerar todas las funciones que se llaman en una aplicación. Intenté usar GDB, pero su lista de backtrace solo hasta la llamada a la función principal.
Necesito una lista más profunda, es decir, una lista de todas las funciones a las que llama la función principal y la función a la que se llama desde estas funciones llamadas, etc.
¿Hay una manera de obtener esto en gdb? ¿O podría darme sugerencias sobre cómo obtener esto?
¿Cómo podemos enumerar todas las funciones que se llaman en una aplicación?
Para cualquier aplicación de tamaño realista, esta lista tendrá miles de entradas, lo que probablemente la hará inútil.
Puede encontrar todas las funciones definidas (pero no necesariamente llamadas) en una aplicación con el comando nm
, por ejemplo
nm /path/to/a.out | egrep '' [TW] ''
También puede usar GDB para establecer un punto de interrupción en cada función:
(gdb) set logging on # collect trace in gdb.txt
(gdb) set confirm off # you wouldn''t want to confirm every one of them
(gdb) rbreak . # set a breakpoint on each function
Una vez que continúe, llegará a un punto de interrupción para cada función llamada. Use los comandos disable
y continue
para avanzar. No creo que haya una manera fácil de automatizar eso, a menos que quieras usar scripts de Python.
Ya mencionado gprof
es otra buena opción.
Esta pregunta podría necesitar una aclaración para decidir entre lo que actualmente son 2 respuestas. Depende de lo que necesites:
1) Debe saber cuántas veces se llama a cada función en formato de lista / gráfico directo de funciones que coinciden con el número de llamadas. Esto podría llevar a resultados ambiguos / no concluyentes si su código no es de procedimiento (es decir, funciones que llaman a otras funciones en una estructura de bifurcación sin ambigüedad de lo que está llamando a qué). Esta es la funcionalidad básica de gprof que requiere la recompilación con el indicador -pg.
2) Necesita una lista de funciones en el orden en que fueron llamadas, esto depende de su programa, que es la mejor opción posible: a) SI su programa se ejecuta y finaliza sin errores de tiempo de ejecución, puede usar gprof para este propósito. b) La opción ELSE anterior que usa dbg con puntos de registro y de interrupción es la opción que sobra y que aprendí al leer esto.
3) Debe conocer no solo el orden, sino también, por ejemplo, los argumentos de la función para cada llamada. Mi trabajo actual es simulaciones en la física del transporte de partículas, por lo que esto sería absolutamente útil para rastrear de dónde provienen resultados anómalos ... es decir, cuando los argumentos que se transmiten dejan de tener sentido. Imagino que una forma de hacerlo es mediante una variación de lo que hizo Employed Russian, excepto utilizando lo siguiente:
(gdb) información args
El registro de los resultados de este comando con cada punto de interrupción (establecido en cada llamada de función) proporciona los argumentos de la función actual.
Quieres un gráfico de llamadas. La herramienta que desea utilizar no es gdb, es gprof
. Usted compila su programa con -pg
y luego lo ejecuta. Cuando se ejecute un archivo se producirá gmon.out
. Luego procesa este archivo con gprof
y disfruta de la salida.
función de registro-historial de llamadas
https://sourceware.org/gdb/onlinedocs/gdb/Process-Record-and-Replay.html
Esto debería ser una gran posibilidad de aceleración de hardware si usted es una de las pocas personas (2015) con una CPU que admite Intel Processor Tracing (Intel PT, intel_pt
en /proc/cpuinfo
).
Los documentos de GDB afirman que puede producir resultados como:
(gdb) list 1, 10
1 void foo (void)
2 {
3 }
4
5 void bar (void)
6 {
7 ...
8 foo ();
9 ...
10 }
(gdb) record function-call-history /ilc
1 bar inst 1,4 at foo.c:6,8
2 foo inst 5,10 at foo.c:2,3
3 bar inst 11,13 at foo.c:9,10
Antes de usarlo necesitas ejecutar:
start
record btrace
que es donde una CPU no capaz falla con:
Target does not support branch tracing.
El soporte de la CPU se discute más a fondo en: ¿Cómo ejecutar el historial de instrucciones de registro y el historial de llamadas de función en GDB?
Temas relacionados:
- ¿Cómo rastrear la función de llamada en C?
- ¿Existe una característica del compilador para inyectar una entrada de función personalizada y un código de salida?
Para incrustado, también considera JTAG y el hardware de soporte como DSTREAM de ARM, pero el soporte de x86 no parece muy bueno: depurar el kernel x86 usando un depurador de hardware