맥에서 qemu GDB로 디버깅하기
docker를 이용하여 gdb 디버깅하는 법
Created Apr 5, 2024 - Last updated: Apr 5, 2024
시작
이번에 qemu를 이용해서 risc-v에서 돌아가는 xv6이라는 운영체제에 대해서 공부하고있는데요. 문제는 현재 맥에서 xv6를 돌리다보니 gdb를 이용해서 디버깅할 수 없다는 것이었습니다. 저는 리눅스 컴퓨터가 없는 관계로 utm으로 리눅스 가상머신을 돌리거나 도커를 이용해야했는데 도커가 훨씬 간편하게 돌릴 수 있을 것 같아 도커에 우분투를 설치하고, 거기서 GDB를 이용하여 xv6를 디버깅하기로 결정했습니다!
진행
컨테이너 만들기
우선 도커 컨테이너를 만들었습니다. 지금은 간단하게 디버깅용으로 사용할 우분투 환경이 필요한 것이니 따로 dockerfile
이나 docker-compose
같은 것은 구성하지 않고 바로 도커 컨테이너를 만들었습니다.
docker run -it -v ~/xv6-riscv-snu:/os --name os ubuntu /bin/bash
이렇게하면 ubuntu 이미지를 이용하여 도커 컨테이너가 생성됩니다. 그 후 /os
폴더와 제 컴퓨터의 ~/xv6-riscv-snu
경로가 볼륨으로 연결됩니다. 그리고 터미널을 통해서 컨테이너에 바로 접근할 수 있죠.
환경 세팅
이후 환경 세팅을 진행해줍니다. 우선은 gcc, vim, gdb정도만 있으면 되겠죠.
apt update
apt-get install gcc vim gdb
진행
제 원래 컴퓨터에는 ~/xv6-riscv-snu
폴더 안에 모든 xv6관련 코드들이 다 있었는데 이 폴더는 지금 도커와 볼륨으로 연결되어있으니 도커 안에서 /os
로 접근하면 똑같은 내용을 볼 수 있겠죠? 컨테이너 안에서는 추가적으로 qemu만 설치해주면 되겠습니다.
{{
그러면 이제 우선 os폴더 안에서 make qemu-gdb
를 통해서 디버깅할 준비를 해주고 다른 터미널 창에서 gdb kernel/kernel
을 입력하고 포트 번호를 입력해 디버깅을 시작해줍니다.
{{
아래는 디버깅을 진행하는 영상입니다. 디버깅 진행 시 사용되는 명령어는 다음과 같습니다.
- b : breakpoint, 멈출 지점을 정합니다.
- c : continue, 다음 breakpoint까지 진행합니다.
- s : step, 한 줄씩 넘어갑니다. 함수를 만나면 내부로 진입합니다.
- si : stepi, 기계어 단위로 한 줄씩 명령어를 실행합니다.
영상 속 내용은 time이라는 제 custom system call을 만들었는데, 이 시스템 콜안에서 ecall이라는 trap을 발생시켰을 때 어디로 뛰게되는지 보려고 한 것이고, mtvec으로 설정된 timervec으로 뛰는 것을 확인하는 영상입니다. 관련 내용은 제 다른 시스템 콜 관련 글에서 확인하실 수 있습니다.