The Chromium Chronicle n. 13: debug per i viaggi nel tempo con RR

Episodio 13: di Christian Biesinger in Madison, WI (marzo 2020)
Puntate precedenti

Ti capita di eseguire lo stesso test più volte nel debugger, a capire com'è che il codice non stava funzionava correttamente. Abbiamo uno strumento che fa per te. Facile da installare e configurare, registra una traccia di esecuzione e fornisce nuovi poteri magici per gdb. Fai un passo indietro e scopri dove hanno modificato il loro valore o quando una funzione è stata chiamata per l'ultima volta su un oggetto (utilizzando punti di interruzione condizionali).

Su Linux, puoi utilizzare rr. Installa tramite sudo apt-get install rr o da https://rr-project.org/.

Questa funzionalità non è ufficialmente supportata, ma molto utile. Il funzionamento di rr è che devi registrare prima una traccia e poi riprodurla di nuovo.

rr record .../content_shell --no-sandbox  --disable-hang-monitor --single-process
# record the trace. --single-process is optional, see below. The other flags are required.
rr replay # This will replay the last trace
(gdb)       # rr uses GDB to let you replay traces

Comodamente, tempi e indirizzi dei cursori rimangono invariati ogni volta che riproduci la riproduzione la stessa traccia. Le tracce possono essere rese portatili con rr pack per copiarli su un'altra macchina e guardarli di nuovo o anche dopo in fase di ricompilazione. Esegui il programma utilizzando continue. Puoi usare tutte le normali funzionalità Comandi GDB -b, next, watch e così via. Tuttavia, puoi anche utilizzare reverse-next (rn), reverse-cont (rc), reverse-step (rs), reverse-fin.

che rispettano comunque eventuali punti di interruzione impostati. Ad esempio:

(gdb) c  # Execute to the end
(gdb) break blink::LayoutFlexibleBox::UpdateLayout
(gdb) rc # Run back to the last layout call
Thread 5 hit Breakpoint 1, blink::LayoutBlock::UpdateLayout (
    this=0x121672224010)
(gdb) # Inspect anything you want here. To find the previous Layout call on this object:
(gdb) cond 1 this == 0x121672224010
(gdb) rc
Thread 5 hit Breakpoint 1, blink::LayoutBlock::UpdateLayout (
    this=0x121672224010)
(gdb) watch -l style_.ptr_ # Or find the last time the style_ was changed
(gdb) rc
Thread 5 hit Hardware watchpoint 2: -location style_.ptr_

Old value = (const blink::ComputedStyle *) 0x1631ad3dbb0
New value = (const blink::ComputedStyle *) 0x0
0x00007f68cabcf78e in std::__Cr::swap<blink::ComputedStyle const*> (

In questo esempio ho usato --single-process per semplicità, ma questo è non è necessario. Il recupero crediti può tracciare più processi; Dopo la registrazione, puoi vedi un elenco utilizzando rr ps e scegline uno da riprodurre con rr replay -f PID.

Le RR possono essere utili in molti modi. Esistono altri comandi che puoi usare, ad esempio quando scoprire il numero dell'evento a cui ti trovi o rr replay -M per annotare stdout con un ID di processo e un numero di evento per ogni riga. Consulta consulta la documentazione e il sito web RR per ulteriori dettagli.