It was a year ago in a nvim-gdb issue #151 that I discovered rr. It promised to allow recording a program execution once, and debugging that run multiple times exactly the same way. Finally, there turned up an occasion to try it in the real life, and to implement the suggestion in the issue.

The task at hand was to investigate how FFmpeg calculates the video frames presentation timestamps for some compressed video stream. That’s what can be seen by executing 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

It looks like the sequence of frames is I-P-B-B-P-B-B etc. It makes perfect sense. But where does the number 1 for the first frame come from? It can be traced by following the memory assignment backward in the history. So let’s record the execution of 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]

Then the debugging can be started by just typing rr replay. But it’s worth doing that in nvim-gdb to enable proper code navigation and highlighting. There’s a demo of how I did it:

asciicast