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

에피소드 13: 위스콘신주 매디슨의 크리스찬 비싱어 작성 (2020년 3월)
이전 에피소드

디버거에서 동일한 테스트를 반복해서 실행하면서 코드의 상태가 어떻게 잘못되었는지 파악하려고 하시나요? 나만을 위한 도구를 준비했습니다. 설치와 설정이 간편하며 실행 트레이스가 기록되므로 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 등을 사용할 수 있습니다. 그러나 역방향 다음 (rn), 역방향 연속 (rc), 역방향 단계 (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은 다양한 방식으로 활용될 수 있습니다. 사용할 수 있는 다른 명령어도 있습니다. 예를 들어, 현재 어떤 이벤트 번호를 찾는지 알아내야 하는 경우 또는 각 줄의 프로세스 ID와 이벤트 번호로 stdout를 주석 처리하는 rr replay -M가 있습니다. 자세한 내용은 RR 웹사이트 및 문서를 참고하세요.