2009-04-29 24 views
32

Qualcuno può dirmi come eseguire il debug in runtime su librerie condivise?Come eseguire il debug in fase di debug delle librerie condivise?

Ho bisogno di eseguire il runtime di una funzione nella mia libreria condivisa, ma è chiamato da un altro programma. Come posso fare qualcosa come dbx con le librerie condivise?

Sto usando dbx su AIX. è migliore di gbb rispetto a dbx per quello che sto cercando di fare?

risposta

28

Devi solo chiamare gdb con l'eseguibile (non importa se è tuo o di terzi). Ecco un esempio in cui eseguo il debug del comando ls e imposto un punto di interruzione nella libreria (condivisa) (condivisa). Questo esempio utilizza gdb 6.8 che supporta la differita punti di interruzione (in corso) che rende questo facile:

gdb /bin/ls 
GNU gdb 6.8-debian 
Copyright (C) 2008 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-linux-gnu"... 
(no debugging symbols found) 
(gdb) b write 
Function "write" not defined. 
Make breakpoint pending on future shared library load? (y or [n]) y 
Breakpoint 1 (write) pending. 
(gdb) r 
Starting program: /bin/ls 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
(no debugging symbols found) 
[Thread debugging using libthread_db enabled] 
(no debugging symbols found) 
(no debugging symbols found) 
[New Thread 0x7f98d2d23780 (LWP 7029)] 
[Switching to Thread 0x7f98d2d23780 (LWP 7029)] 

Breakpoint 1, 0x00007f98d2264bb0 in write() from /lib/libc.so.6 
(gdb) 

Come si può vedere gdb gestisce automaticamente tutte le discussioni utilizzati dal file eseguibile. Non devi fare niente di speciale per i thread lì. Il punto di interruzione funzionerà in qualsiasi thread.

In alternativa, se si desidera connettere il debugger a un'applicazione già in esecuzione (io uso tail -f/tmp/ttt qui come esempio):

ps ux | grep tail 
lothar 8496 0.0 0.0 9352 804 pts/3 S+ 12:38 0:00 tail -f /tmp/ttt 
lothar 8510 0.0 0.0 5164 840 pts/4 S+ 12:39 0:00 grep tail 

gdb 
GNU gdb 6.8-debian 
Copyright (C) 2008 Free Software Foundation, Inc. 
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> 
This is free software: you are free to change and redistribute it. 
There is NO WARRANTY, to the extent permitted by law. Type "show copying" 
and "show warranty" for details. 
This GDB was configured as "x86_64-linux-gnu"... 
(no debugging symbols found) 
(gdb) attach 8496 
Attaching to program: /usr/bin/tail, process 8496 
Reading symbols from /lib/librt.so.1...(no debugging symbols found)...done. 
Loaded symbols for /lib/librt.so.1 
Reading symbols from /lib/libc.so.6...(no debugging symbols found)...done. 
Loaded symbols for /lib/libc.so.6 
Reading symbols from /lib/libpthread.so.0...(no debugging symbols found)...done. 
[Thread debugging using libthread_db enabled] 
[New Thread 0x7f24853f56e0 (LWP 8496)] 
Loaded symbols for /lib/libpthread.so.0 
Reading symbols from /lib/ld-linux-x86-64.so.2... 
(no debugging symbols found)...done. 
Loaded symbols for /lib64/ld-linux-x86-64.so.2 
(no debugging symbols found) 
0x00007f2484d2bb50 in nanosleep() from /lib/libc.so.6 
(gdb) b write 
Breakpoint 1 at 0x7f2484d57bb0 
(gdb) c 
Continuing. 
[Switching to Thread 0x7f24853f56e0 (LWP 8496)] 

Breakpoint 1, 0x00007f2484d57bb0 in write() from /lib/libc.so.6 
(gdb) 
+0

I usato dbx su AIX. se dici che gdb può farlo con applicazioni filettate .. poi dbx fa schifo alla grande .. e sono stato un pazzo totale ad usarlo tutto questo tempo. –

+0

Sad gdb non funziona correttamente su AIX ... AIX fa schifo .. –

+0

Non so dbx, ma dovrebbe avere caratteristiche simili – lothar

9

Normalmente la procedura per il debug di una libreria condivisa è molto simile a quella per il debug di un eseguibile: la differenza principale è che potrebbe non essere possibile impostare un punto di interruzione finché la libreria condivisa non viene caricata in memoria. Si collega il debugger all'eseguibile principale.

Se si esegue il debug di un'applicazione che non è di proprietà dell'utente, ma si sta utilizzando il modulo in un'architettura di plug-in, si utilizza ancora lo stesso metodo. Assicurati (come sempre) di disporre delle informazioni di debug disponibili per la tua libreria condivisa. In Windows, si dovrebbe generare un file .pdb. Con gcc, penso che si specifica uno speciale flag di compilatore (-g?) Per garantire che vengano fornite le informazioni di debug. Alleghi il debugger all'applicazione di terze parti.

+0

e se l'eseguibile principale non è mio ed è di qualche terza parte .... ma sto scrivendo un modulo che verrà usato dal terzo partito ... Come si fa il debug allora? –

+0

Si avvia ancora l'eseguibile (o si collega a un processo) con gdb. Dopo aver caricato la libreria, gdb può impostare i punti di interruzione senza problemi. – lothar

+0

Ma quando si imposta un punto di interruzione nel codice lib condiviso e se l'eseguibile principale lo chiama, non si bloccherà l'eseguibile principale ?? –

1

Ricordo di aver provato le librerie condivise creando un'app finta che lo usava. Se sei disposto a fare un sacco di lavoro, potresti creare una seconda libreria condivisa finta che raccoglie solo informazioni su come la libreria viene utilizzata dall'app di terze parti, e poi fai in modo che la tua app di simulazione riproduca tali informazioni.

Naturalmente, non dubitare mai delle potenti chiamate printf e fprintf.

0

Si potrebbe provare a compilare e collegare la libreria staticamente per eseguirne il debug.
Se il bug si presenta solo quando è compilato come condiviso, allora potrebbe darti qualche indizio.

1

E 'stato un lungo periodo di tempo da quando ho ho dovuto usare dbx su AIX, e ho affrontato anche questo problema. Installare gdb non era un'opzione per me.

dbx /path/to/your/program 
(dbx) run [args to your program] 
(dbx) set $ignoreonbptrap   # I kept hitting a trace/bpt trap 
(dbx) set $deferevents    # allows setting bp in not loaded shared library 
(dbx) set $repeat     # useful, repeat commands with <enter> tjust like gdb 
(dbx) stop in MySharedLibraryFunc # defers breakpoint 
(dbx) cont 
3

Un altro esempio in seguito alla risposta di Lothar:

Io corro test su una libreria dinamica test.so (compilato da test.c) in Linux utilizzando la libreria di unit test python e di pitone unittest chiamato tests/test_pwmbasic.py.(Schema di denominazione è un po 'monotono, mi rendo conto che ora)

~/my/test/path/ 
    tests/ 
     __init__.py 
     test_pwmbasic.py 
    test.c 
    test.so 

voglio eseguire il debug di ciò che è in test.so da stimolo test_pwmbasic.py. Quindi questo è come ho ottenuto che funziona ...

$ cd ~/my/test/path 
$ gdb $(which python) 
    ... gdb blah ... 
(gdb) b test.c:179 
(gdb) run 
>>> from tests.test_pwmbasic import * 
>>> import unittest 
>>> unittest.main() 
    ... unittest blah ... 
Breakpoint 1, pwmTest_setDutyCycles (dutyCycles=0x7ffff7ece910) at ./test.c:179 
(gdb) print pwm_errorCode 
$1 = PWM_ERROR_NONE 

e ora voglio sposare gdb

nota: test.c include anche ../pwm.c, così posso anche punto di interruzione all'interno di quella biblioteca con

(gdb) b pwm.c:123 
Problemi correlati