mozilla rr
є більш надійною альтернативою зворотній налагодженні GDB
https://github.com/mozilla/rr
Вбудований запис та повторне відтворення GDB має серйозні обмеження, наприклад, відсутність підтримки інструкцій AVX: зворотне налагодження gdb не вдається з "Запис процесу не підтримує інструкцію 0xf0d за адресою"
Недоліки rr:
- в даний час набагато надійніше. Я протестував його відносно тривалий цикл декількох складних програм.
- також пропонує інтерфейс GDB з протоколом gdbserver, що робить його чудовою заміною
- невелике падіння продуктивності для більшості програм, я сам цього не помітив, не роблячи вимірювань
- згенеровані сліди невеликі на диску, оскільки записано дуже мало недетермінованих подій, мені ніколи не доводилося турбуватися про їх розмір
rr досягає цього, спочатку запускаючи програму таким чином, щоб фіксувати те, що відбувалося з кожною окремою недетермінованою подією, такою як перемикач потоків.
Потім під час другого запуску повторного використання він використовує той файл трасування, який напрочуд малий, щоб реконструювати саме те, що сталося в початковому недетермінованому запуску, але детермінованим способом, вперед чи назад.
Спочатку rr був розроблений Mozilla, щоб допомогти їм відтворити помилки синхронізації, які виявилися під час щовечірнього тестування наступного дня. Але зворотний аспект налагодження також є фундаментальним для того, коли у вас є помилка, яка трапляється лише години в процесі виконання, оскільки ви часто хочете зробити крок назад, щоб перевірити, який попередній стан призвів до пізнішої помилки.
Наступний приклад демонструє деякі з його особливостей, в зокрема reverse-next
, reverse-step
і reverse-continue
команду.
Встановити на Ubuntu 18.04:
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
Програма випробувань:
#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;
}
компілюємо та запускаємо:
gcc -O0 -ggdb3 -o reverse.out -std=c89 -Wextra reverse.c
rr record ./reverse.out
rr replay
Тепер ви залишились у сеансі GDB, і ви можете правильно змінити налагодження:
(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;
Під час налагодження складного програмного забезпечення ви, швидше за все, добігнете до точки збою, а потім потрапите в глибокий кадр. У цьому випадку не забувайте, що для reverse-next
вищих кадрів спочатку потрібно:
reverse-finish
до цього кадру up
недостатньо просто зробити звичайне .
На мою думку, найсерйознішими обмеженнями rr є:
UndoDB є комерційною альтернативою rr: https://undo.io Обидва базуються на відстеженні / відтворенні, але я не впевнений, як вони порівнюються з точки зору функцій та продуктивності.