Рік тому у проблемі #151 у nvim-gdb я відкрив для себе rr. Проєкт обіцяв дати можливість записати виконання програми один раз, і відтворювати хід програми багато разів щоразу однаковим чином. Нарешті випала нагода випробувати це на справжній задачі, і виконати те, що було запропоновано у проблемі №151.

Переді мною була задача розслідувати, як FFmpeg обчислює часові мітки показу кадрів для деякого стисненого потоку відео. Їх можна побачити з допомогою ffprobe:

ffprobe -loglevel -8 -i test.mp4 -select_streams v -show_entries packet=pts | grep pts | head
pts=1
pts=4
pts=2
pts=3
pts=7
pts=5
pts=6

Схоже на послідовність кадрів I-P-B-B-P-B-B etc. Цілком очікувано. Але звідки з’являється число 1 для першого кадру? Можна відслідкувати копіювання в пам’ять у історії роботи програми. Тож спершу запишімо роботу програми ffprobe:

$ rr record ffprobe -loglevel -8 -i stream.mpd -select_streams v -show_entries packet=pts                
rr: Saving execution to trace directory `/home/sakhnik/.local/share/rr/ffprobe-4'.
[PACKET]
pts=1
[/PACKET]
[PACKET]
pts=3
[/PACKET]
[PACKET]
pts=2
[/PACKET]

Тоді відтворення програми в GDB можна запустити, просто виконавши rr replay. Проте варто зробити це у nvim-gdb щоб мати змогу виконувати навігацію по коду і отримати звичне розфарбовування тексту. Ось демонстрація, як це вийшло у мене:

asciicast