Posso impostare un breakpoint su "accesso alla memoria" in GDB?


244

Sto eseguendo un'applicazione tramite gdb e voglio impostare un breakpoint ogni volta che si accede / cambia una specifica variabile. C'è un buon metodo per farlo? Sarei anche interessato ad altri modi per monitorare una variabile in C / C ++ per vedere se / quando cambia.

Risposte:


286

guarda solo le interruzioni in scrittura, rwatch ti consente di interrompere in lettura e awatch ti consente di interrompere in lettura / scrittura.

È possibile impostare i punti di controllo di lettura nelle posizioni di memoria:

gdb$ rwatch *0xfeedface
Hardware read watchpoint 2: *0xfeedface

ma una limitazione si applica ai comandi rwatch e awatch; non puoi usare le variabili gdb nelle espressioni:

gdb$ rwatch $ebx+0xec1a04f
Expression cannot be implemented with read/access watchpoint.

Quindi devi espanderli tu stesso:

gdb$ print $ebx 
$13 = 0x135700
gdb$ rwatch *0x135700+0xec1a04f
Hardware read watchpoint 3: *0x135700 + 0xec1a04f
gdb$ c
Hardware read watchpoint 3: *0x135700 + 0xec1a04f

Value = 0xec34daf
0x9527d6e7 in objc_msgSend ()

Modifica: Oh, e comunque. È necessario il supporto hardware o software . Il software è ovviamente molto più lento. Per scoprire se il tuo sistema operativo supporta watchpoint hardware, puoi vedere l' impostazione dell'ambiente can-use-hw-watchpoints .

gdb$ show can-use-hw-watchpoints
Debugger's willingness to use watchpoint hardware is 1.

7
Se si vuole guardare un membro di metodo di un C ++, ho trovato questa variante estremamente utile: watch -location mTextFormatted.
Ivan Vučica,

Cosa succede se non ho l'indirizzo di una variabile? Posso solo usare il suo nome?
Raffi Khatchadourian,

5
Puoi far stampare a GDB l'indirizzo della variabile con l'operatore address-of. print &variable
Loduwijk,

1
Questa risposta non dice nulla sulla dimensione della posizione della memoria che viene controllata dai watchcomandi. Nel frattempo, questa è la prima domanda che viene in mente dopo aver letto quanto sopra. Quanti byte rwatch *0xfeedfaceguarderanno effettivamente?
AnT

8
@AnT, stavo supponendo che avrebbe guardato un singolo byte, il che sembra essere il caso, ma puoi lanciarlo su un tipo specifico ad esempio rwatch *(int *)0xfeedfacee guarderà i sizeof(int)byte: sourceware.org/gdb/onlinedocs/gdb/Set-Watchpoints. html
chiede il

28

Quello che stai cercando si chiama watchpoint .

uso

(gdb) watch foo: guarda il valore della variabile foo

(gdb) watch *(int*)0x12345678: guarda il valore puntato da un indirizzo , inserito nel tipo che desideri

(gdb) watch a*b + c/d: guarda un'espressione arbitrariamente complessa , valida nella lingua madre del programma

I punti di controllo sono di tre tipi:

  • watch : gdb si interromperà quando si verifica una scrittura
  • rwatch : gdb si interromperà quando si verifica una lettura
  • awatch : gdb si interromperà in entrambi i casi

Puoi scegliere il più appropriato per le tue esigenze.

Per ulteriori informazioni, controlla questo .


5
Ho scritto un'altra risposta perché quelle esistenti non mi sembravano molto semplici ...
Paolo M

25

Supponendo che la prima risposta si riferisca alla sintassi simil-C, (char *)(0x135700 +0xec1a04f)la risposta da fare rwatch *0x135700+0xec1a04fè errata. La sintassi corretta è rwatch *(0x135700+0xec1a04f).

La mancanza di ()s lì mi ha causato molta sofferenza nel tentativo di usare i punti di controllo da solo.


9

Ho appena provato quanto segue:

 $ cat gdbtest.c
 int abc = 43;

 int main()
 {
   abc = 10;
 }
 $ gcc -g -o gdbtest gdbtest.c
 $ gdb gdbtest
 ...
 (gdb) watch abc
 Hardware watchpoint 1: abc
 (gdb) r
 Starting program: /home/mweerden/gdbtest 
 ...

 Old value = 43
 New value = 10
 main () at gdbtest.c:6
 6       }
 (gdb) quit

Quindi sembra possibile, ma sembra che tu abbia bisogno di supporto hardware.


Se la tua piattaforma non supporta watchpoint hardware, gdb dovrebbe ricadere su un watchpoint software.
Tod

2

Usa watch per vedere quando viene scritta una variabile, rwatch quando viene letta e sbloccata quando viene letta / scritta da / a, come indicato sopra. Tuttavia, si noti che per utilizzare questo comando, è necessario interrompere il programma e la variabile deve rientrare nell'ambito quando si è rotto il programma:

Usa il comando watch. L'argomento del comando watch è un'espressione che viene valutata. Ciò implica che la variabel su cui si desidera impostare un punto di controllo deve trovarsi nell'ambito corrente. Pertanto, per impostare un punto di controllo su una variabile non globale, è necessario aver impostato un punto di interruzione che interromperà il programma quando la variabile rientra nell'ambito. Si imposta il punto di controllo dopo l'interruzione del programma.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.