Эпизод 13: Кристиан Бизингер, Мэдисон, Висконсин (март 2020 г.)
Предыдущие серии
Случается ли вам, что вы снова и снова запускаете один и тот же тест в отладчике, пытаясь выяснить, почему код оказался в плохом состоянии? У нас есть инструмент для вас! Он прост в установке и настройке, записывает трассировку выполнения, что дает gdb
новые волшебные возможности. Сделайте шаг назад, запустите назад , посмотрите, где переменные изменили свое значение или когда функция в последний раз вызывалась для объекта (с использованием условных точек останова).
В Linux вы можете использовать rr . Установите с помощью sudo apt-get install rr
или с https://rr-project.org/ .
Это официально не поддерживается, но очень полезно. Принцип работы rr
заключается в том, что вы сначала записываете трассировку , а затем воспроизводите ее .
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
Удобно, что адреса времени и указателя остаются неизменными каждый раз, когда вы воспроизводите одну и ту же трассу. Трассировки можно сделать переносимыми с помощью rr pack
, чтобы их можно было скопировать на другую машину и воспроизвести там или воспроизвести даже после перекомпиляции. Запустите программу, используя continue
. Вы можете использовать все обычные команды GDB -b
, next
, watch
и т. д. Однако вы также можете использоватьverse -next ( rn
), reverse-cont ( rc
), reverse-step ( rs
), reverse-fin .
Они по-прежнему учитывают любые установленные вами точки останова. Например:
(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*> (
В этом примере я использовал --single-process
для простоты, но это не обязательно. RR может отслеживать несколько процессов ; после записи вы можете просмотреть список с помощью rr ps
и выбрать один для воспроизведения с помощью rr replay -f PID
.
Есть много способов, которыми RR может быть полезен. Вы можете использовать и другие команды , например, When, чтобы узнать, на каком номере события вы находитесь, или rr replay -M
чтобы аннотировать stdout
идентификатором процесса и номером события для каждой строки. Дополнительную информацию см. на веб-сайте RR и в документации .