Chrome nettleser, Nyheter

The Chromium Chronicle: Time-Travel Debugging with RR

The Chromium Chronicle: Time-Travel Debugging with RR

Episode 13: March, 2020

by Christian Biesinger in Madison, WI

Do you find yourself running the same test over and over in the debugger,
trying to figure out how the code got in a bad state? We have a tool for you!
Easy to install and setup, it will record an execution trace, and that gives
magical new powers to gdb. Step backwards, run backwards, see where
variables changed their value or when a function was last called on an object
(using conditional breakpoints).

On Linux, you can use rr. Install using sudo apt-get install rr or
from https://rr-project.org/.

This is not officially supported, but very useful. The way rr works is that
you first record a trace, then replay it.

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

Conveniently, timing and pointer addresses stay the same every time you replay
the same trace. Traces can be made portable using rr pack so that you
can copy them to another machine and replay there, or replay even after
recompiling. Run your program using continue. You can use all regular
GDB commands -b, next, watch, etc. However, you can also use
reverse-next (rn), reverse-cont (rc), reverse-step (rs),
reverse-fin.

These still respect any breakpoints you’ve set. For example:

(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 this example, I have used --single-process for simplicity, but that’s
not necessary. RR can trace multiple processes; after recording, you can
see a list using rr ps and pick one to replay with rr replay -f PID.

There are lots of ways RR can be useful. There are other commands you can use,
such as when to find out at which event number you are at, or rr replay -M
to annotate stdout with a process ID and event number for each line. See
the RR website and documentation for more details.

This post is also available in: English

author-avatar

About Aksel Lian

En selvstendig full stack webutvikler med en bred variasjon av kunnskaper herunder SEO, CMS, Webfotografi, Webutvikling inkl. kodespråk..