A volte devo rintracciare molte chiamate di funzione, anche per le librerie esterne non ho alcun controllo, o non voglio modificare.
Un po 'di tempo fa, mi sono reso conto che è possibile combinare i punti di interruzione delle espressioni regolari di gdb (anche quelli regolari sono ok) e quindi eseguire una serie di comandi da eseguire ogni volta che vengono attivati questi punti di interruzione. Vedere: http://www.ofb.net/gnu/gdb/gdb_35.html
Ad esempio, se si vuole tracciare tutte le funzioni che iniziano con il prefisso "MPI_", si può fare:
(gdb) rbreak MPI_
[...]
(gdb) command 1-XX
(gdb) silent
(gdb) bt 1
(gdb) echo \n\n
(gdb) continue
(gdb) end
comando silenzioso viene utilizzata per nascondere i messaggi gdb quando viene trovato un punto di interruzione . Di solito stampo un paio di righe vuote, in modo che sia più facile da leggere.
Poi, basta eseguire il programma: (gdb) gestita
Una volta che il programma inizia l'esecuzione, gdb stamperà i più alti livelli di Backtrace N.
#0 0x000000000040dc60 in [email protected]()
#0 PMPI_Initialized (flag=0x7fffffffba78) at ../../src/mpi/init/initialized.c:46
#0 0x000000000040d9b0 in [email protected]()
#0 PMPI_Init_thread (argc=0x7fffffffbe78, argv=0x7fffffffbde0, required=3, provided=0x7fffffffba74) at ../../src/mpi/init/initthread.c:946
#0 0x000000000040e390 in [email protected]()
#0 PMPI_Comm_rank (comm=1140850688, rank=0x7fffffffba7c) at ../../src/mpi/comm/comm_rank.c:53
#0 0x000000000040e050 in [email protected]()
#0 PMPI_Type_create_struct (count=3, array_of_blocklengths=0x7fffffffba90, array_of_displacements=0x7fffffffbab0, array_of_types=0x7fffffffba80, newtype=0x69de20) at ../../src/mpi/datatype/type_create_struct.c:116
#0 0x000000000040e2a0 in [email protected]()
#0 PMPI_Type_commit (datatype=0x69de20) at ../../src/mpi/datatype/type_commit.c:75
Se volete informazioni più dettagliate, la stampa di variabili locali di un dato punto di interruzione è anche possibile, basta inserire più comandi tra command
e end
.
Suggerimento bonus: aggiungi tutti questi al tuo file .gdbinit
e conduci l'esecuzione in un file.
Utilizzare un debugger. Oppure invocare qualche forma di registrazione fprintf in un file. Ma forse le ultime opzioni non sarebbero buone visto che non si desidera modificare il codice sorgente. – Lefteris
Forse un profiler per ottenere un grafico delle chiamate? –
Stai cercando qualcosa del genere? http://stackoverflow.com/questions/311840/tool-to-trace-local-function-calls-in-linux – delannoyk