2014-11-12 12 views
9

Desidero impostare un punto di interruzione su un parametro funzione se è maggiore di un determinato valore. codice fittizio di seguito:Interruzione condizionale GDB su parametro funzione

int main(void) 
{ 
    uint64_t num = 123456; 
    uint64_t x = 847534; 

    uint64_t other = (num*x) - (x/num); 

    .... other stuff here (multithreaded stuff) 

    calc(other); 
} 

void calc(uint64_t size) 
{ 
    ...do some stuff with size 
} 

Ho cercato di impostare un punto di interruzione:

(gdb) b calc if size == 852479 

ma non sa che cosa è formato dal momento che è un parametro sto cercando di indovinare. Come potrei interrompere se il parametro è uguale a un certo numero. NON è un'opzione per interrompere tutte le chiamate a questa funzione perché viene chiamata un miliardo di volte nell'ambiente multithread.

+0

possibile duplicato di [Come impostare un punto di interruzione condizionale in gdb, quando char \ * fa riferimento a una stringa il cui valore equivale a "ciao"?] (Http://stackoverflow.com/questions/4183871/how-do -i-set-a-condizionale-breakpoint-in-gdb-quando-char-x-punti-a-una-stringa-wh) –

+0

Hai provato a impostare il punto di interruzione sulla prima riga del codice funzione? – Leeor

+1

@RickyMutschlechner Ho guardato a quello 1 e non è un duplicato perché nel caso di quel codice x (la variabile in questione) si presume che sia disponibile da gdb per interrompere perché è una variabile dichiarata al di fuori di una funzione. Nel mio caso questa variabile è il parametro di una funzione. Sono in grado di rompere con successo le variabili dichiarate al di fuori di una funzione ma non in grado di rompere i parametri tramite l'interruzione condizionale –

risposta

3

dal gdb messaggio:

break "file.c":100 if (size=852479) 

o

break "file.c":100 if (size>852479) 

qui io parto dal presupposto che si desidera che il punto di interruzione condizionale sulla linea 100 e il file src è file.c

cioè se si desidera per rompere sulla linea che chiama calc, quindi quella sarebbe la riga 100 - modificare come appropriato (si dovrebbe anche sostituire size con other in questo caso)

se si utilizza una linea n. che è stato uno dei 1 ° affermazioni nella funzione calc allora si dovrebbe attaccare con size

+0

Il problema che sto avendo è gdb non è a conoscenza della "dimensione" prima di avviare il programma, probabilmente perché è un nome di parametro e non una variabile dichiarata al di fuori di una funzione. Una cosa che sto provando in questo momento è impostare un punto di interruzione sulla funzione, eseguendo il programma, ora gdb è consapevole della variabile di dimensione e ora sto facendo un'interruzione di condizione su quella variabile. Nell'esempio qui sotto (gdb) rottura file.c: calc (gdb) eseguire Breakpoint 1, calc (size = 48) a file.c: 67 \t in file.c (gdb) b se la dimensione = 852479 // Qui è dove la dimensione è effettivamente riconosciuta da gdb (gdb) c –

+0

gdb è a conoscenza di qualsiasi cosa * prima * di avviare il programma? 'altro' è una variabile dichiarata e istanziata prima della chiamata al calc, quindi non dovresti avere problemi nell'impostare un breakpoint condizionale su di esso (forse sto ancora fraintendendo la domanda qui?) – bph

4

Supponendo x86-64 calling conventions su piattaforma GNU/Linux si potrebbe esaminare %rdi (64-bit) registrarsi direttamente per verificare primo parametro della funzione:

b calc if $rdi == 852479 

Ciò consente di interrompere la funzione calc anche se non sono stati caricati i simboli di debug (quindi nessun elenco di codici, ad esempio list calc).

Si noti che questo metodo non funzionerebbe se la funzione è in linea con optimizing compiler.

2

Se break foo if arg1 == 14 non funziona per qualche motivo (ho incontrato alcune funzioni/binari dove si trova, e dove non lo fa), puoi provare a sostituirlo con commands.

commands consente di impostare alcuni comandi gdb che verranno eseguiti ogni volta che viene raggiunto il punto di interruzione. Per ottenere l'effetto desiderato - un punto di interruzione condizionale - è possibile effettuare le seguenti operazioni:

(gdb) b foo 
Breakpoint 1 at 0x400633: file test.c, line 6. 
(gdb) commands 1 
Type commands for breakpoint(s) 1, one per line. 
End with a line saying just "end". 
>silent 
>if arg1 != 14 
>cont 
>end 
>end 

L'esecuzione si fermerà davanti a breakpoint solo se arg1 == 14.

L'unico inconveniente è che silent elimina il tipico messaggio "hitpoint di interruzione". È possibile rimuovere silent, ma gdb stamperà il messaggio anche se il punto di interruzione viene saltato dallo script commands, che non è desiderabile se il punto di interruzione viene colpito molto spesso.

È tuttavia possibile aggiungere alcune notifiche personalizzate all'interno dello script command.