# 디버깅 도구 설정 및 활용

실시간 애플리케이션 개발에서는 정확하고 효율적인 디버깅이 필수적이다. 특히, **Preempt RT** 환경에서는 일반적인 리눅스 디버깅 기법에 더해 실시간성을 고려한 디버깅이 요구된다. 이 절에서는 다양한 디버깅 도구를 설정하고 활용하는 방법을 설명한다.

#### GDB (GNU Debugger)

**GDB**는 가장 널리 사용되는 디버깅 도구로, C/C++로 작성된 프로그램을 디버깅하는 데 주로 사용된다. **Preempt RT** 환경에서 **GDB**를 사용하기 위해서는 몇 가지 추가 설정이 필요하다.

1. **설치**:

   ```bash
   sudo apt-get install gdb
   ```
2. **기본 설정**: **GDB**는 `gdbinit` 파일을 통해 초기 설정을 자동으로 불러올 수 있다. 개발 환경에서 디버깅을 시작할 때마다 특정 설정을 반복하지 않으려면, 홈 디렉터리에 `.gdbinit` 파일을 생성하여 다음과 같은 설정을 추가한다.

   ```bash
   set print pretty on
   set pagination off
   ```
3. **RT 애플리케이션 디버깅**: **Preempt RT** 커널은 일반 커널과는 다르게 실시간 스케줄링을 지원하므로, 특정 시점에서의 시스템 상태를 확인하는 것이 중요하다. **GDB**를 사용해 RT 애플리케이션을 디버깅할 때는 **set scheduler-locking on** 명령을 사용하여 스케줄러의 간섭 없이 특정 스레드를 집중적으로 분석할 수 있다.

   ```gdb
   set scheduler-locking on
   ```

   이 설정을 통해, 실시간 스레드의 상태를 정확히 추적할 수 있다.

#### KGDB (Kernel GNU Debugger)

**KGDB**는 **커널 모드**에서 실행되는 코드를 디버깅할 수 있도록 해주는 도구이다. **Preempt RT**에서 커널 레벨의 디버깅이 필요할 때 매우 유용하다.

1. **KGDB 설정**: 커널 디버깅을 위해, 커널을 **KGDB** 지원 옵션으로 빌드해야 한다. **Linux Kernel**을 빌드할 때 다음과 같은 옵션을 활성화한다.

   ```plaintext
   CONFIG_KGDB=y
   CONFIG_KGDB_SERIAL_CONSOLE=y
   CONFIG_KGDB_KDB=y
   ```

   이 설정을 활성화한 후, 커널을 재빌드하고 부팅한다.
2. **KGDB 활용**: 부팅 후, **KGDB**를 활성화하려면 시리얼 콘솔이나 네트워크 콘솔을 통해 커널 디버깅을 시작할 수 있다.

   ```bash
   echo ttyS0 > /sys/module/kgdboc/parameters/kgdboc
   gdb vmlinux
   ```

   여기서 `ttyS0`는 디버깅에 사용되는 시리얼 포트이다. **GDB** 명령어를 사용하여 커널 모드에서 실행되는 코드를 중단, 분석, 수정할 수 있다.

#### Trace-cmd와 Ftrace

**Trace-cmd**는 **Ftrace** 기반의 리눅스 트레이싱 도구로, 실시간 시스템에서 타이밍 분석 및 디버깅에 널리 사용된다.

1. **설치**:

   ```bash
   sudo apt-get install trace-cmd
   ```
2. **기본 사용법**: **Trace-cmd**를 사용하여 시스템 콜, 스케줄링 이벤트, 인터럽트 등의 타이밍을 분석할 수 있다. 다음은 **Trace-cmd**를 사용하여 특정 이벤트를 기록하고 분석하는 방법이다.

   ```bash
   sudo trace-cmd record -e sched_switch -e irq_handler_entry
   ```

   이 명령은 스케줄링 변경(sched\_switch)과 인터럽트 핸들러 진입(irq\_handler\_entry) 이벤트를 기록한다.
3. **로그 분석**: 기록된 로그는 **Trace-cmd**를 통해 분석할 수 있으며, 이를 시각적으로 분석하기 위해 **Kernelshark**와 같은 툴을 사용할 수도 있다.

   ```bash
   sudo trace-cmd report
   ```

   이 명령은 기록된 트레이스를 분석하여, 시스템에서 발생한 이벤트의 타임라인을 출력한다.

#### LTTng (Linux Trace Toolkit Next Generation)

**LTTng**는 고급 트레이싱 도구로, 시스템 수준에서의 성능 및 실시간 애플리케이션 동작을 분석할 때 유용하다. **LTTng**는 커널 및 사용자 공간에서 이벤트를 추적할 수 있으며, 복잡한 실시간 시스템에서 발생하는 문제를 분석하는 데 도움을 준다.

1. **설치**: **LTTng** 도구와 관련 패키지를 설치한다.

   ```bash
   sudo apt-get install lttng-tools lttng-modules-dkms babeltrace
   ```
2. **세션 생성 및 추적 시작**: **LTTng** 세션을 생성하고, 추적할 이벤트를 설정한 후 추적을 시작한다.

   ```bash
   lttng create my-session
   lttng enable-event -k -a  # 커널의 모든 이벤트를 추적
   lttng start
   ```

   이 명령어들은 `my-session`이라는 이름의 세션을 생성하고, 커널의 모든 이벤트를 추적하도록 설정한 후 추적을 시작한다.
3. **추적 중지 및 결과 분석**: 추적을 종료하고 결과를 분석한다.

   ```bash
   lttng stop
   lttng view
   ```

   `lttng stop` 명령어로 추적을 중지한 후, `lttng view` 명령어로 기록된 이벤트를 볼 수 있다.

#### Valgrind

**Valgrind**는 메모리 디버깅, 메모리 누수 탐지, 성능 프로파일링 등을 지원하는 도구이다. 실시간 애플리케이션 개발에서는 메모리 누수와 같은 문제들이 시스템의 실시간성을 저해할 수 있기 때문에, 이러한 문제를 사전에 탐지하는 것이 중요하다.

1. **설치**:

   ```bash
   sudo apt-get install valgrind
   ```
2. **기본 사용법**: **Valgrind**는 다양한 도구들을 제공하지만, 메모리 누수를 탐지하기 위해서는 `memcheck` 도구를 사용한다.

   ```bash
   valgrind --leak-check=full ./your-application
   ```

   이 명령어는 프로그램을 실행하면서 메모리 누수를 탐지한다.
3. **결과 분석**: **Valgrind**는 메모리 할당과 해제, 메모리 접근 오류 등을 추적하여 보고서를 제공한다. 보고서를 통해 메모리 관련 버그를 찾아낼 수 있다.

#### SystemTap

**SystemTap**는 동적인 커널 추적 도구로, 실시간 애플리케이션의 성능 및 동작을 깊이 있게 분석할 수 있다. **SystemTap**은 커널 모듈을 동적으로 삽입하여 다양한 커널 및 사용자 공간 이벤트를 추적할 수 있다.

1. **설치**:

   ```bash
   sudo apt-get install systemtap systemtap-sdt-dev
   ```
2. **스크립트 작성 및 실행**: **SystemTap** 스크립트를 작성하여 커널 이벤트를 추적한다.

   ```bash
   stap -e 'probe kernel.function("do_fork") { printf("Fork detected: %s\n", execname()) }'
   ```

   이 스크립트는 `do_fork` 함수가 호출될 때마다 해당 이벤트를 출력한다.
3. **추적 결과 분석**: **SystemTap**는 실행 중에 추적된 정보를 실시간으로 출력할 수 있으며, 복잡한 시스템 동작을 분석하는 데 매우 유용하다.

#### GDB와 QEMU 연동

**QEMU**와 **GDB**를 연동하여 가상 환경에서의 실시간 애플리케이션을 디버깅할 수 있다. 이 방법은 물리적인 하드웨어에 접근하기 어려운 경우에 매우 유용하다.

1. **QEMU 설치**:

   ```bash
   sudo apt-get install qemu
   ```
2. **QEMU에서의 GDB 서버 실행**: **QEMU**에서 GDB 서버를 실행하여, 가상 머신 내의 코드를 디버깅할 수 있다.

   ```bash
   qemu-system-x86_64 -s -S -kernel bzImage
   ```

   `-s` 옵션은 **QEMU**에서 **GDB** 서버를 시작하고, `-S` 옵션은 부팅을 중지한 상태로 대기하도록 설정한다.
3. **GDB 연결**: **GDB**를 실행하고 **QEMU**의 GDB 서버에 연결한다.

   ```gdb
   target remote localhost:1234
   ```

   이 명령어를 통해 **GDB**를 **QEMU**에 연결하고 디버깅을 시작할 수 있다.
