Record & Replay 프로젝트를 어떻게 구현할지에 대한 방향을 적어둔 문서로서, 여기에 적힌 내용을 기준으로 프로젝트를 수행해 나간다.
구현 목표
VPOS 커널 상에서 프로그램이 수행하다가 오류가 발생하여 시스템이 정지했을 때, 디버깅을 위하여 문제점 재현을 가능하게 해준다.
프로그램의 오류가 발생하기 전까지는 수행 정보를 저장하고 있기 때문에 오류가 발생하기전 상태로 재현할 수 있다.
해야할 것들
- 프로그램의 수행도중에 예기치 못한 오류가 발생했을 경우, 그 당시의 정보를 저장하기 위한 매체로 Flash 메모리로 결정했다. 그러므로 R/W 할 수 있어야 한다.
- 타겟 시스템을 Break 할 수 있도록 해야한다.
해결되어야 할 문제점
- 멀티 코어 환경에서 Global Stop and Record 기능
- I/O 상황 재현 기능
- CPU 내부(캐쉬, 파이프라인) 기능
- Slow replay and debug(기존의 디버거에서의 step by step 기능)
동작
인터럽트 발생시(컨텍스트 스위칭 포함)
- 인터럽트 핸들러의 실행으로 발생했을 당시의 모든 메모리 상태가 flash 에 저장된다. 이때 모든 인터럽트를 disable 된다.
- 수행이 끝나면, 모든 인터럽트는 enable 된다.
익셉션 발생시
- 개발자가 작성한 애플리케이션이 수행도중 익셉션이 발생하면서, 뻗었다.
- 익셉션 핸들러가 동작하면서, 명령어를 입력받을 수 있는 쉘 방식의 프롬프트가 실행된다.
- ls 를 입력하면, 현재 상태에서 사용할 수 있는 명령어가 출력된다. bt, register, thread, mem dump 등이 그것이다. bt 는 익셉션이 발생한 시점의 백트레이스를 보여주고, register 는 당시의 레지스터 값, thread 는 당시의 쓰레드 상태와 주소(ready 큐), mem dump 는 특정 메모리의 영역을 보여준다.
- back next 명령어를 이용해서 저장된 컨텍스트를 이동할 수 있다.
타겟 부팅시
- 타겟을 재부팅하면, 최소한의 환경(하드웨어, 소프트웨어 초기화)가 완료된 시점에서 바로 수행을 할 것인지, 아니면, 디버깅 모드로 진입할 것인지를 선택한다.
- 디버깅 모드를 선택하면, flash 메모리의 특정 블럭의 header 를 읽어서 저장된 컨텍스트의 갯수와 위치, 주소를 알아낸다. 이 정보는 부팅 시에 출력되며, 선택할 수 있다.
select? [1] timer.c time_init() line 32 [2] thread.c thread_create() line 126 [3] irq.c irq_request() line 44
- 숫자를 선택하면, 해당 컨텍스트가 저장되었던 flash 주소를 메모리로 읽어들여서 복구함으로서 컨텍스트가 발생했던 시기로 돌아간다.
- 명령어를 이용해서 컨텍스트 당시의 변수, 메모리상태를 볼 수 있다.
그외 사항
- record & replay 관련한 함수는 라이브러리 형태로 만들어, 애플리케이션 개발자가 일반 api 를 사용함으로서 원하는 지점에서 record & replay 디버깅이 가능하도록 한다.
요구사항
- 컨텍스트가 일어난 시점으로 이동하기 위해서는 전체 메모리 영역을 저장하고 있어야 한다.