Mozilla rr
https://github.com/mozilla/rr
Der in GDB integrierte Datensatz und die Wiedergabe weisen schwerwiegende Einschränkungen auf, z. B. keine Unterstützung für AVX-Anweisungen: Das Reverse-Debugging von GDB schlägt mit "Prozessdatensatz unterstützt Anweisung 0xf0d an Adresse nicht fehl" fehl.
Oberseite von rr:
- derzeit viel zuverlässiger. Ich habe es relativ lange Läufe von mehreren komplexen Software getestet.
- bietet auch eine GDB-Schnittstelle mit gdbserver-Protokoll, was es zu einem großartigen Ersatz macht
- kleiner Leistungsabfall für die meisten Programme, ich habe es selbst nicht bemerkt, ohne Messungen durchzuführen
- Die generierten Spuren sind auf der Festplatte klein, da nur sehr wenige nicht deterministische Ereignisse aufgezeichnet werden. Bisher musste ich mir keine Gedanken über ihre Größe machen
Das folgende Beispiel zeigt einige seiner Funktionen, vor allem die reverse-next
, reverse-step
und reverse-continue
Befehle.
Unter Ubuntu 18.04 installieren:
sudo apt-get install rr linux-tools-common linux-tools-generic linux-cloud-tools-generic
sudo cpupower frequency-set -g performance
# Overcome "rr needs /proc/sys/kernel/perf_event_paranoid <= 1, but it is 3."
echo 'kernel.perf_event_paranoid=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
Testprogramm:
reverse.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int f() {
int i;
i = 0;
i = 1;
i = 2;
return i;
}
int main(void) {
int i;
i = 0;
i = 1;
i = 2;
/* Local call. */
f();
printf("i = %d\n", i);
/* Is randomness completely removed?
* Recently fixed: https://github.com/mozilla/rr/issues/2088 */
i = time(NULL);
printf("time(NULL) = %d\n", i);
return EXIT_SUCCESS;
}
kompilieren und ausführen:
gcc -O0 -ggdb3 -o reverse.out -std=c89 -Wextra reverse.c
rr record ./reverse.out
rr replay
Jetzt befinden Sie sich in einer GDB-Sitzung und können das Debuggen ordnungsgemäß rückgängig machen:
(rr) break main
Breakpoint 1 at 0x55da250e96b0: file a.c, line 16.
(rr) continue
Continuing.
Breakpoint 1, main () at a.c:16
16 i = 0;
(rr) next
17 i = 1;
(rr) print i
$1 = 0
(rr) next
18 i = 2;
(rr) print i
$2 = 1
(rr) reverse-next
17 i = 1;
(rr) print i
$3 = 0
(rr) next
18 i = 2;
(rr) print i
$4 = 1
(rr) next
21 f();
(rr) step
f () at a.c:7
7 i = 0;
(rr) reverse-step
main () at a.c:21
21 f();
(rr) next
23 printf("i = %d\n", i);
(rr) next
i = 2
27 i = time(NULL);
(rr) reverse-next
23 printf("i = %d\n", i);
(rr) next
i = 2
27 i = time(NULL);
(rr) next
28 printf("time(NULL) = %d\n", i);
(rr) print i
$5 = 1509245372
(rr) reverse-next
27 i = time(NULL);
(rr) next
28 printf("time(NULL) = %d\n", i);
(rr) print i
$6 = 1509245372
(rr) reverse-continue
Continuing.
Breakpoint 1, main () at a.c:16
16 i = 0;
rr erreicht dies, indem das Programm zunächst so ausgeführt wird, dass aufgezeichnet wird, was bei jedem einzelnen nicht deterministischen Ereignis passiert ist, z. B. bei einem Thread-Wechsel.
Während des zweiten Wiederholungslaufs wird diese überraschend kleine Ablaufverfolgungsdatei verwendet, um genau das zu rekonstruieren, was beim ursprünglichen nicht deterministischen Lauf passiert ist, jedoch auf deterministische Weise, entweder vorwärts oder rückwärts.
rr wurde ursprünglich von Mozilla entwickelt, um ihnen zu helfen, Timing-Fehler zu reproduzieren, die bei ihren nächtlichen Tests am nächsten Tag auftraten. Der Aspekt des umgekehrten Debuggens ist jedoch auch von grundlegender Bedeutung, wenn Sie einen Fehler haben, der nur Stunden innerhalb der Ausführung auftritt, da Sie häufig einen Schritt zurücktreten möchten, um zu untersuchen, welcher vorherige Status zu dem späteren Fehler geführt hat.
Die schwerwiegendsten Einschränkungen von rr sind meiner Meinung nach:
UndoDB ist eine kommerzielle Alternative zu rr: https://undo.io Beide basieren auf Trace / Replay, aber ich bin mir nicht sicher, wie sie sich in Bezug auf Funktionen und Leistung vergleichen lassen.