실시간 애플리케이션 개발에서는 정확하고 효율적인 디버깅이 필수적이다. 특히, Preempt RT 환경에서는 일반적인 리눅스 디버깅 기법에 더해 실시간성을 고려한 디버깅이 요구된다. 이 절에서는 다양한 디버깅 도구를 설정하고 활용하는 방법을 설명한다.
GDB (GNU Debugger)
GDB는 가장 널리 사용되는 디버깅 도구로, C/C++로 작성된 프로그램을 디버깅하는 데 주로 사용된다. Preempt RT 환경에서 GDB를 사용하기 위해서는 몇 가지 추가 설정이 필요하다.
-
설치:
bash sudo apt-get install gdb
-
기본 설정: GDB는
gdbinit
파일을 통해 초기 설정을 자동으로 불러올 수 있다. 개발 환경에서 디버깅을 시작할 때마다 특정 설정을 반복하지 않으려면, 홈 디렉터리에.gdbinit
파일을 생성하여 다음과 같은 설정을 추가한다.
bash
set print pretty on
set pagination off
- RT 애플리케이션 디버깅: Preempt RT 커널은 일반 커널과는 다르게 실시간 스케줄링을 지원하므로, 특정 시점에서의 시스템 상태를 확인하는 것이 중요하다. GDB를 사용해 RT 애플리케이션을 디버깅할 때는 set scheduler-locking on 명령을 사용하여 스케줄러의 간섭 없이 특정 스레드를 집중적으로 분석할 수 있다.
gdb
set scheduler-locking on
이 설정을 통해, 실시간 스레드의 상태를 정확히 추적할 수 있다.
KGDB (Kernel GNU Debugger)
KGDB는 커널 모드에서 실행되는 코드를 디버깅할 수 있도록 해주는 도구이다. Preempt RT에서 커널 레벨의 디버깅이 필요할 때 매우 유용하다.
- KGDB 설정: 커널 디버깅을 위해, 커널을 KGDB 지원 옵션으로 빌드해야 한다. Linux Kernel을 빌드할 때 다음과 같은 옵션을 활성화한다.
plaintext
CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_KDB=y
이 설정을 활성화한 후, 커널을 재빌드하고 부팅한다.
- KGDB 활용: 부팅 후, KGDB를 활성화하려면 시리얼 콘솔이나 네트워크 콘솔을 통해 커널 디버깅을 시작할 수 있다.
bash
echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
gdb vmlinux
여기서 ttyS0
는 디버깅에 사용되는 시리얼 포트이다. GDB 명령어를 사용하여 커널 모드에서 실행되는 코드를 중단, 분석, 수정할 수 있다.
Trace-cmd와 Ftrace
Trace-cmd는 Ftrace 기반의 리눅스 트레이싱 도구로, 실시간 시스템에서 타이밍 분석 및 디버깅에 널리 사용된다.
-
설치:
bash sudo apt-get install trace-cmd
-
기본 사용법: Trace-cmd를 사용하여 시스템 콜, 스케줄링 이벤트, 인터럽트 등의 타이밍을 분석할 수 있다. 다음은 Trace-cmd를 사용하여 특정 이벤트를 기록하고 분석하는 방법이다.
bash
sudo trace-cmd record -e sched_switch -e irq_handler_entry
이 명령은 스케줄링 변경(sched_switch)과 인터럽트 핸들러 진입(irq_handler_entry) 이벤트를 기록한다.
- 로그 분석: 기록된 로그는 Trace-cmd를 통해 분석할 수 있으며, 이를 시각적으로 분석하기 위해 Kernelshark와 같은 툴을 사용할 수도 있다.
bash
sudo trace-cmd report
이 명령은 기록된 트레이스를 분석하여, 시스템에서 발생한 이벤트의 타임라인을 출력한다.
LTTng (Linux Trace Toolkit Next Generation)
LTTng는 고급 트레이싱 도구로, 시스템 수준에서의 성능 및 실시간 애플리케이션 동작을 분석할 때 유용하다. LTTng는 커널 및 사용자 공간에서 이벤트를 추적할 수 있으며, 복잡한 실시간 시스템에서 발생하는 문제를 분석하는 데 도움을 준다.
- 설치: LTTng 도구와 관련 패키지를 설치한다.
bash
sudo apt-get install lttng-tools lttng-modules-dkms babeltrace
- 세션 생성 및 추적 시작: LTTng 세션을 생성하고, 추적할 이벤트를 설정한 후 추적을 시작한다.
bash
lttng create my-session
lttng enable-event -k -a # 커널의 모든 이벤트를 추적
lttng start
이 명령어들은 my-session
이라는 이름의 세션을 생성하고, 커널의 모든 이벤트를 추적하도록 설정한 후 추적을 시작한다.
- 추적 중지 및 결과 분석: 추적을 종료하고 결과를 분석한다.
bash
lttng stop
lttng view
lttng stop
명령어로 추적을 중지한 후, lttng view
명령어로 기록된 이벤트를 볼 수 있다.
Valgrind
Valgrind는 메모리 디버깅, 메모리 누수 탐지, 성능 프로파일링 등을 지원하는 도구이다. 실시간 애플리케이션 개발에서는 메모리 누수와 같은 문제들이 시스템의 실시간성을 저해할 수 있기 때문에, 이러한 문제를 사전에 탐지하는 것이 중요하다.
-
설치:
bash sudo apt-get install valgrind
-
기본 사용법: Valgrind는 다양한 도구들을 제공하지만, 메모리 누수를 탐지하기 위해서는
memcheck
도구를 사용한다.
bash
valgrind --leak-check=full ./your-application
이 명령어는 프로그램을 실행하면서 메모리 누수를 탐지한다.
- 결과 분석: Valgrind는 메모리 할당과 해제, 메모리 접근 오류 등을 추적하여 보고서를 제공한다. 보고서를 통해 메모리 관련 버그를 찾아낼 수 있다.
SystemTap
SystemTap는 동적인 커널 추적 도구로, 실시간 애플리케이션의 성능 및 동작을 깊이 있게 분석할 수 있다. SystemTap은 커널 모듈을 동적으로 삽입하여 다양한 커널 및 사용자 공간 이벤트를 추적할 수 있다.
-
설치:
bash sudo apt-get install systemtap systemtap-sdt-dev
-
스크립트 작성 및 실행: SystemTap 스크립트를 작성하여 커널 이벤트를 추적한다.
bash
stap -e 'probe kernel.function("do_fork") { printf("Fork detected: %s\n", execname()) }'
이 스크립트는 do_fork
함수가 호출될 때마다 해당 이벤트를 출력한다.
- 추적 결과 분석: SystemTap는 실행 중에 추적된 정보를 실시간으로 출력할 수 있으며, 복잡한 시스템 동작을 분석하는 데 매우 유용하다.
GDB와 QEMU 연동
QEMU와 GDB를 연동하여 가상 환경에서의 실시간 애플리케이션을 디버깅할 수 있다. 이 방법은 물리적인 하드웨어에 접근하기 어려운 경우에 매우 유용하다.
-
QEMU 설치:
bash sudo apt-get install qemu
-
QEMU에서의 GDB 서버 실행: QEMU에서 GDB 서버를 실행하여, 가상 머신 내의 코드를 디버깅할 수 있다.
bash
qemu-system-x86_64 -s -S -kernel bzImage
-s
옵션은 QEMU에서 GDB 서버를 시작하고, -S
옵션은 부팅을 중지한 상태로 대기하도록 설정한다.
- GDB 연결: GDB를 실행하고 QEMU의 GDB 서버에 연결한다.
gdb
target remote localhost:1234
이 명령어를 통해 GDB를 QEMU에 연결하고 디버깅을 시작할 수 있다.