Folge 13:von Christian Biesinger in Madison, Wisconsin, USA (März 2020)
Vorherige Folgen
Führen Sie immer wieder denselben Test im Debugger aus, um herauszufinden, warum der Code fehlerhaft ist? Wir haben ein Tool für dich!
Der Dienst ist einfach zu installieren und einzurichten. Er zeichnet einen Ausführungs-Trace auf, was gdb
magische neue Möglichkeiten verleiht. Gehen Sie einen Schritt zurück, laufen Sie zurück und sehen Sie sich an, wo Variablen ihren Wert geändert haben oder wann eine Funktion zuletzt für ein Objekt aufgerufen wurde (mit bedingten Haltepunkten).
Unter Linux können Sie rr verwenden. Installieren Sie das Projekt mit sudo apt-get install rr
oder über https://rr-project.org/.
Dies wird offiziell nicht unterstützt, ist aber sehr hilfreich. rr
funktioniert so, dass Sie zuerst einen Trace aufzeichnen und dann wiederholen.
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
Praktischerweise bleiben Timing und Zeigeradressen bei jeder Wiedergabe desselben Trace gleich. Traces können mit rr pack
portiert werden, sodass Sie sie auf einen anderen Computer kopieren und dort wiedergeben oder auch nach einer Neukompilierung noch einmal wiedergeben können. Führen Sie Ihr Programm mit continue
aus. Sie können alle regulären GDB-Befehle -b
, next
, watch
usw. verwenden. Sie können aber auch reverse-next (rn
), reverse-cont (rc
), reverse-step (rs
) und reverse-fin verwenden.
Auch hier werden alle von Ihnen festgelegten Haltepunkte berücksichtigt. Beispiel:
(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 diesem Beispiel habe ich der Einfachheit halber --single-process
verwendet, aber das ist nicht erforderlich. RR kann mehrere Prozesse verfolgen. Nach der Aufnahme können Sie mit rr ps
eine Liste aufrufen und einen Prozess für die erneute Wiedergabe mit rr replay -f PID
auswählen.
RR kann auf viele Arten nützlich sein. Es gibt weitere Befehle, die Sie verwenden können, z. B. wann Sie herausfinden, bei welcher Ereignisnummer Sie sich befinden, oder rr replay -M
, um stdout
mit einer Prozess-ID und einer Ereignisnummer für jede Zeile zu annotieren. Weitere Informationen finden Sie auf der RR-Website und -Dokumentation.