Chromium Chronicle n°13: débogage du voyage dans le temps avec RR

Épisode 13:par Christian Biesinger à Madison, Wisconsin (mars 2020)
Épisodes précédents

Vous arrive-t-il d'exécuter le même test sans cesse dans le débogueur ? essayer de comprendre comment le code s’est mal passé ? Nous avons un outil pour vous ! Facile à installer et à configurer, il enregistre une trace d'exécution et donne de nouveaux pouvoirs magiques pour gdb. Reculez, courez en arrière, voyez où variables ont modifié leur valeur ou la date à laquelle une fonction a été appelée pour la dernière fois sur un objet (à l'aide de points d'arrêt conditionnels).

Sous Linux, vous pouvez utiliser rr. Installer avec sudo apt-get install rr ou de https://rr-project.org/.

Cette fonctionnalité n'est pas officiellement compatible, mais est très utile. Voici comment fonctionne rr : vous enregistrez d'abord une trace, puis vous la rejouez.

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

Pratiquement, les adresses de minutage et de pointeur restent les mêmes chaque fois que vous rejouez la même trace. Vous pouvez rendre les traces portables à l'aide de rr pack : vous pouvez les copier sur une autre machine et les rejouer sur celle-ci, ou les relancer de la recompilation. Exécutez votre programme à l'aide de continue. Vous pouvez utiliser Commandes GDB -b, next, watch, etc. Toutefois, vous pouvez aussi utiliser inverser (rn), inverser (rc), inverser (rs), inverser.

Elles respectent toujours les points d'arrêt que vous avez définis. Exemple :

(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*> (

Dans cet exemple, j'ai utilisé --single-process par souci de simplicité, ce n'est pas nécessaire. RR peut tracer plusieurs processus. après l'enregistrement, vous pouvez voir une liste avec rr ps et en choisir une pour la relancer avec rr replay -f PID.

Il existe de nombreuses façons dont RR peut être utile. Vous pouvez utiliser d'autres commandes. par exemple, pour savoir à quel numéro d'événement vous vous trouvez, ou rr replay -M. pour annoter stdout avec un ID de processus et un numéro d'événement pour chaque ligne. Voir le site Web et la documentation de RR pour en savoir plus.