Chromium Chronicle #13: RR을 사용한 시간 이동 디버깅

에피소드 13: 크리스찬 비진저, 위스콘신주 매디슨 (2020년 3월)
이전 에피소드

디버거에서 동일한 테스트를 반복해서 실행하시나요? 코드가 어떻게 나쁜 상태가 되었는지 알아내려고 할 때 어떻게 해야 할까요? YouTube에 크리에이터님을 위한 도구가 마련되어 있습니다. 설치와 설정이 용이하고, 실행 트레이스를 기록하고, 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 등입니다. 하지만 reverse-next (rn), reverse-cont (rc), reverse-step (rs), 역방향 핀입니다.

설정한 모든 중단점을 계속 따릅니다. 예를 들면 다음과 같습니다.

(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은 여러 가지 방식으로 활용할 수 있습니다. 사용할 수 있는 다른 명령어도 있지만 예를 들어 현재 참석 중인 이벤트 번호를 확인할 시간 또는 rr replay -M 각 줄에 프로세스 ID와 이벤트 번호로 stdout에 주석을 추가합니다. 자세한 내용은 자세한 내용은 RR 웹사이트 및 문서를 참고하세요.