# 디버깅 기법 및 도구

디버깅은 실시간 애플리케이션 개발에서 매우 중요한 단계로, 시스템의 신뢰성 및 성능을 확보하기 위해 필수적이다. Preempt RT 환경에서의 디버깅은 일반적인 시스템에서의 디버깅과는 차이가 있다. 이는 실시간 특성을 유지하면서도 오류를 찾아 수정해야 하기 때문이다. 이 절에서는 Preempt RT 실시간 애플리케이션의 디버깅 기법과 주요 도구에 대해 다룬다.

#### 디버깅 기법

**1. 커널 트레이싱 (Kernel Tracing)**

커널 트레이싱은 실시간 시스템에서 중요한 디버깅 기법이다. 커널 수준에서 발생하는 이벤트를 기록하여, 특정 문제의 원인을 파악하는 데 유용하다. Preempt RT에서는 실시간 특성을 유지하면서도 트레이싱을 수행할 수 있는 여러 도구가 제공된다.

* **ftrace**: Linux 커널에 내장된 트레이싱 프레임워크로, 함수 호출, 스케줄링 이벤트, IRQ 핸들링 등의 다양한 이벤트를 추적할 수 있다.
* **trace-cmd**와 **KernelShark**: `ftrace`의 프론트엔드 도구로, 추적된 데이터를 시각화하고 분석하는 데 도움을 준다.

**2. gdb와 kgdb**

`gdb`는 널리 사용되는 디버깅 도구로, Preempt RT에서도 사용할 수 있다. 특히 커널 디버깅을 위한 `kgdb`는 커널 수준에서 직접 디버깅을 할 수 있는 강력한 도구이다.

* **원격 디버깅**: 실시간 시스템에서는 중단점 설정이 실시간 성능에 영향을 미칠 수 있기 때문에, 원격 디버깅을 통해 시스템에 최소한의 부하만을 주면서 문제를 해결할 수 있다.
* **스냅샷 디버깅**: 실시간 애플리케이션의 상태를 특정 시점에서 캡처하여, 그 시점의 상태를 분석함으로써 실시간 특성에 영향을 주지 않고 디버깅을 수행할 수 있다.

**3. 로그 기반 디버깅**

실시간 애플리케이션에서는 중단점 설정이 전체 시스템의 동작에 영향을 줄 수 있기 때문에, 로그 기반 디버깅이 자주 사용된다. 로그 기반 디버깅은 시스템이 실행되는 동안의 상태를 기록하고, 이를 통해 문제를 추적한다.

* **printk**: 커널 모드에서 메시지를 출력하는 함수로, 실시간 시스템에서는 로그 레벨과 버퍼 크기를 신중하게 설정해야 한다.
* **syslog**와 **journald**: 사용자 공간에서 로그를 수집하고 분석하는 도구로, 실시간 시스템에서도 적용할 수 있다.

**4. 실시간 분석 도구**

Preempt RT 시스템의 실시간 성능을 분석하기 위해, 전용 분석 도구들이 필요하다. 이러한 도구들은 주로 타이밍 분석과 관련된 문제를 추적하는 데 사용된다.

* **cyclictest**: 주로 실시간 응답 시간의 분석에 사용되는 도구로, 특정 주기마다 타이머 인터럽트를 발생시키고, 실제 발생한 시간과의 차이를 측정하여 시스템의 지연 특성을 분석한다.
* **latencytop**: 커널에서 발생하는 지연 원인을 분석하는 도구로, 실시간 시스템에서 중요한 지연 요소를 파악하는 데 유용하다.

**5. 동기화 문제 디버깅**

실시간 시스템에서는 여러 스레드나 프로세스가 동시에 자원을 공유할 때, 동기화 문제가 발생할 수 있다. 이러한 문제는 실시간 특성에 큰 영향을 미칠 수 있기 때문에, 특별한 주의가 필요하다.

* **Lockdep**: 커널 내에서 잠금 순서의 위반을 감지하여, 데드락과 같은 동기화 문제를 예방할 수 있도록 돕는 도구이다.
* **spinlock과 mutex 디버깅**: Preempt RT에서는 스핀락과 뮤텍스의 사용이 일반적이다. 이러한 동기화 메커니즘을 사용할 때 발생할 수 있는 잠금 경쟁 문제와 우선순위 역전 문제를 효과적으로 디버깅하는 방법을 다룬다.

#### 디버깅 도구

Preempt RT 환경에서 실시간 애플리케이션을 디버깅하기 위해 다양한 도구들이 사용된다. 아래에서는 이러한 도구들의 주요 기능과 사용 방법에 대해 설명한다.

**1. ftrace**

`ftrace`는 Linux 커널에 내장된 강력한 트레이싱 프레임워크이다. 이는 실시간 시스템에서의 디버깅에 매우 유용하며, 다양한 트레이싱 옵션을 제공한다.

* **Function Tracer**: 커널 함수 호출을 추적하여, 함수가 호출된 순서와 시간을 기록한다. 이를 통해 함수 간의 의존성과 성능 병목을 파악할 수 있다.
* **Event Tracer**: 커널의 특정 이벤트(예: 스케줄링, 인터럽트)를 추적하여 실시간 시스템에서 발생하는 주요 사건들을 기록한다. 실시간 애플리케이션에서 이벤트의 타이밍을 분석하는 데 유용하다.

**2. perf**

`perf`는 프로파일링 도구로, CPU 성능 카운터를 사용하여 시스템의 성능을 분석한다. Preempt RT 환경에서는 실시간 애플리케이션의 성능 병목을 분석하는 데 사용될 수 있다.

* **Sampling**: CPU 이벤트의 샘플링을 통해 CPU 사용 패턴을 분석하고, 어느 함수가 CPU 시간을 많이 소비하는지 확인할 수 있다.
* **Tracing**: 시스템 콜이나 사용자 정의 이벤트를 추적하여, 시스템의 동작을 세부적으로 분석할 수 있다. 실시간 특성을 유지하면서도 문제를 파악하는 데 도움을 준다.

**3. GDB와 KGDB**

GDB는 널리 사용되는 디버거로, Preempt RT에서의 사용자 애플리케이션뿐만 아니라 커널 디버깅에도 사용할 수 있다. 특히 KGDB는 커널 디버깅에 특화된 도구이다.

* **Breakpoints**: 실시간 애플리케이션에서는 중단점 사용이 제한될 수 있으므로, 상황에 맞게 신중히 사용해야 한다. 이를 통해 특정 코드 경로를 분석할 수 있다.
* **Watchpoints**: 메모리 접근을 감시하여, 실시간 애플리케이션에서 특정 변수의 변경 시점을 파악할 수 있다. 이는 메모리 관련 버그를 추적하는 데 유용하다.

**4. LTTng (Linux Trace Toolkit Next Generation)**

LTTng는 고성능의 낮은 오버헤드를 가진 트레이싱 도구로, Preempt RT 시스템에서 커널과 사용자 공간의 이벤트를 모두 추적할 수 있다.

* **Unified Tracing**: 커널과 사용자 공간에서 발생하는 이벤트를 동시에 추적할 수 있어, 실시간 애플리케이션의 전체적인 동작을 분석하는 데 유용하다.
* **Low Overhead**: LTTng는 매우 낮은 오버헤드를 제공하여, 실시간 특성을 유지하면서도 상세한 트레이스를 제공할 수 있다.

**5. Valgrind**

Valgrind는 메모리 디버깅과 프로파일링을 위한 도구이다. 실시간 애플리케이션에서 메모리 누수나 메모리 접근 오류를 감지하는 데 유용하다.

* **Memcheck**: 메모리 누수, 잘못된 메모리 접근 등을 감지하여, 실시간 애플리케이션의 안정성을 확보하는 데 도움을 준다.
* **Cachegrind**: 캐시 사용 패턴을 분석하여, 캐시 관련 성능 문제를 파악할 수 있다. 이는 실시간 애플리케이션에서의 메모리 접근 성능을 최적화하는 데 유용하다.

**6. DTrace**

DTrace는 시스템 전체의 동작을 실시간으로 분석할 수 있는 동적 트레이싱 프레임워크이다. Preempt RT 환경에서도 사용 가능하며, 실시간 시스템의 성능 분석에 효과적이다.

* **Dynamic Instrumentation**: 실행 중인 시스템의 동작을 실시간으로 분석하고, 특정 조건에 따라 이벤트를 기록할 수 있다.
* **Comprehensive Scripting**: DTrace 스크립트를 사용하여 복잡한 트레이싱 작업을 자동화할 수 있으며, 이를 통해 실시간 애플리케이션의 특정 동작을 심층 분석할 수 있다.

**7. SystemTap**

SystemTap은 Linux 커널을 위한 스크립트 기반의 디버깅 도구로, 실시간 애플리케이션의 내부 동작을 분석하는 데 유용하다.

* **Kernel Probing**: 실시간 커널의 특정 함수나 이벤트에 프로브를 설정하여, 시스템의 동작을 실시간으로 분석할 수 있다.
* **User-space Probing**: 사용자 애플리케이션에서 발생하는 이벤트를 추적하여, 커널과 사용자 공간 간의 상호작용을 분석할 수 있다.

**8. Debugfs**

`debugfs`는 Linux 커널 디버깅을 위해 제공되는 가상 파일 시스템이다. Preempt RT 환경에서는 실시간 애플리케이션의 상태를 직접 확인하고 조정하는 데 사용할 수 있다.

* **Runtime State Inspection**: 커널의 내부 상태를 직접 확인하고, 실시간 애플리케이션에서 발생하는 문제를 실시간으로 분석할 수 있다.
* **Parameter Tuning**: 커널 파라미터를 동적으로 조정하여, 실시간 시스템의 성능을 최적화하거나 문제를 진단할 수 있다.
