2013-12-09 13 views
5
define traverse 
    while(CONDITION) 
     if $start == 0 
      set $start = 1 
      print_node 
      print_rss_item 
     else 
      continue 
      print_node 
      print_rss_item 
     end 
    end 
end 

Quali condizioni devo interrompere il ciclo se il programma è terminato?Come eseguire il ciclo in uno script GDB fino al termine del programma?

+0

Suppongo che '$ start = 1' sia la clausola che arresta il ciclo. Quindi vuoi 'while ($ start == 0)'? Questo link dovrebbe aiutare https://sourceware.org/gdb/onlinedocs/gdb/Command-Files.html – KeithSmith

risposta

0

Semplicemente loop in un ciclo infinito. Uscirà quando il programma è finito.

define traverse 
    while(1) 
     if $start == 0 
      set $start = 1 
      print_node 
      print_rss_item 
     else 
      continue 
      print_node 
      print_rss_item 
     end 
    end 
end 
5

Guardando lo script gdb:

define traverse 
    while(CONDITION) 
     if $start == 0 
      set $start = 1 
      print_node 
      print_rss_item 
     else 
      continue 
      print_node 
      print_rss_item 
     end 
    end 
end 

Molte cose da notare:

  1. Lo script gdb (il cosiddetto "debugger") e del debug sono sempre operando in un commutazione modalità: WHENEVER THE GDB SCRIPT RUN, il debuggee è in pausa e NON è in esecuzione, e ogni volta che il DEBUGGEE è in esecuzione, lo script gdb è in pausa e NON IN CORSO.

  2. Perché è così? Questo perché ogni volta che il debugge è in modalità pausa (leggi l'API "ptrace()" e le sue varie opzioni: PEEKUSER, POKEUSER, PTRACE_CONT) il debugger può effettivamente pulire (e costantemente in memoria) la memoria del debuggee senza timore di corruzione, e quindi tutti i valori variabili ecc

Quando debugger non è in funzione, cioè, eseguita l'operazione "continua", dove il controllo viene passato al debug, il debug può quindi continuare a funzionare e cambiamento la propria memoria, senza paura di essere letto erroneamente da un altro processo - perché non può accadere.

Quindi, come facciamo a sapere quando il debuggee è terminato? Quando "continua" non è riuscito e quindi gdbscript non continuerà a funzionare. Ma se imposti un debuggee senza punti di interruzione, eseguendo il comando gdb "run" troverai il debuggee eseguito continuamente, senza che lo script gdb abbia una possibilità di esecuzione.

Così efficacemente se lo script è in esecuzione, quindi debuggee è in modalità STOP e viceversa. E se il debuggee è terminato chiamando exit(), anche lo script gdb non verrà eseguito.

esempio:

defining the macro (inside .gdbinit file): 

define myloop_print 
set $total = $arg0 
set $i = 0 
    while($i<$total) 
    set $i = $i + 1 
    print $i, $i 
    cont 
    end 
end 

E poi correre "gdb/bin/ls" e seguito da "rompere scrittura" e "run -al" e poi "myloop_print 10000" (la sequenza o ordine è importante) , possiamo vedere che ogni "scrittura" si interromperà e gdbscript stamperà il contatore.

E ultime righe eseguite sono:

Breakpoint 1, write() at ../sysdeps/unix/syscall-template.S:81 
81 in ../sysdeps/unix/syscall-template.S 
$40571 = 285 
drwxrwxr-x 2 tthtlc tthtlc 4096 Feb 18 00:00 yocto_slide 
[Inferior 1 (process 7395) exited normally] 
$40572 = 286 
The program is not being run. 
(gdb) 

che mostra chiaramente che l'ultimo contatore stampato è 286, anche se avevo specificato 10000 come limite.

L'esecuzione della macro senza il debug in esecuzione:

(gdb) myloop_print 10000 
$40573 = 1 
The program is not being run. 
(gdb) 

Possiamo vedere che la gdbscript non verrà eseguito.

E se si esegue "gdb/bin/ls" e seguito da "myloop_print 10000" (supponendo che la macro sia definita all'interno di .gdbinit), si otterrà gdbscript in esecuzione su 10000 loop completi, senza che il debug sia mai in esecuzione.

Problemi correlati