# 사례 연구: 복잡한 실시간 시스템 디버깅

이번 장에서는 복잡한 실시간 시스템의 디버깅 사례 연구를 통해 고급 Xenomai 디버깅 및 프로파일링 기법을 살펴보겠다. 실시간 시스템은 지연 시간과 응답 시간이 중요한 요소인 만큼, 디버깅 과정에서 이를 초점으로 맞춰 문제를 해결하는 것이 핵심이다.

#### 시스템 개요

본 사례 연구에서 다룰 실시간 시스템은 여러 개의 태스크로 구성되어 있으며, 각 태스크는 서로 다른 주기와 우선순위를 가지고 있다. 시스템은 다양한 센서 데이터를 수집하고, 실시간으로 분석하여 출력 장치로 데이터를 전송하는 기능을 한다.

#### 문제 정의

시스템은 예상치 못한 지연을 겪고 있으며, 특정 태스크가 주기적으로 미스된 데드라인을 보이고 있다. 디버깅 과정에서 확인할 문제는 다음과 같다:

* **높은 우선순위를 가진 태스크의 지연**
* **태스크 간의 상호작용 문제**
* **리소스 경합의 가능성**

#### 초기 분석

초기 분석 단계에서는 `dmesg`나 `/var/log/messages`와 같은 로그 파일을 통해 시스템 로그를 확인한다. 또한 `xenomai-stat` 명령어로 각 태스크의 스케줄링 상태와 주기, 우선순위, 실행 시간을 확인한다.

**예상 로그 출력:**

```bash
$ sudo dmesg | grep Xenomai
...
[ 123.456789] Xenomai: Task_1 overrun, resolnce: 2ms
[ 123.567890] Xenomai: Task_2 missed deadline, expected: 10ms, actual: 15ms
...
```

#### 프로파일링 도구 사용

Xenomai는 다양한 프로파일링 도구를 제공한다. 이번 사례에서는 주요 태스크의 실행 시간을 상세히 분석하기 위해 `xeno_profiler`를 사용한다.

**프로파일러 실행 예시:**

```bash
$ xeno_profiler --start
```

태스크 실행 이후, 프로파일러를 중지하고 결과를 분석한다.

```bash
$ xeno_profiler --stop
$ xeno_profiler --report
```

**예상 프로파일러 출력:**

```bash
Task               Avg_exec_time    Max_exec_time    Overruns
--------------------------------------------------------------
Task_1             1.5ms            2.2ms            5
Task_2             8ms              15ms             10
Task_3             0.8ms            1.1ms            0
```

#### 문제 원인 분석

#### 1. 높은 우선순위를 가진 태스크의 지연

첫 단계로, 높은 우선순위를 가진 태스크(Task\_1)에서의 지연을 분석한다. 이 경우, 높은 우선순위를 가지는 태스크가 예상보다 시간이 더 소요되거나, 다른 태스크가 시간을 점유하고 있을 가능성이 있다.

가능한 원인으로는:

* **태스크 자체의 코드 최적화 필요성**
* **다른 태스크와의 우선순위 역전**

#### 2. 태스크 간의 상호작용 문제

각 태스크 간의 상호작용에서 문제가 발생할 수 있다. 예를 들어, `Task_2`가 `Task_1`의 리소스를 기다리며 데드라인을 넘겼을 가능성이 있다. 이를 확인하기 위해, 해당 태스크 간의 뮤텍스(Mutex)나 세마포어(Semaphore) 사용을 체크한다.

#### 3. 리소스 경합의 가능성

마지막으로, 시스템 내에서 리소스를 공유하는 과정에서 경합이 발생할 수 있다. 이는 특히 공유 메모리나 I/O 장치를 접근할 때 발생할 수 있는 문제이다.

복잡한 실시간 시스템 디버깅에는 다음과 같은 기술들이 사용된다:

* **피호출자를 통한 호출 체인 분석 (Call Graphs)**
* **실시간 트레이서 사용**
* **커널 레벨 디버깅 도구 활용**

#### 해결 방안

각 원인 분석에 따른 가능한 해결 방안을 제시한다:

1. **코드 최적화 및 우선순위 조정**
2. **리소스 접근 전략 개선**
3. **고급 트레이싱 기법을 통한 실행 경로 분석**

#### 1. 코드 최적화 및 우선순위 조정

**코드 최적화**

* `Task_1`의 코드 실행 시간을 줄이기 위해 루프와 조건문을 최적화한다.
* 불필요한 연산을 최소화하고, 필요한 연산은 미리 계산하거나 테이블화한다.

**우선순위 조정**

* `Task_2`와 같은 다른 태스크의 우선순위를 재조정함으로써 높은 우선순위 태스크가 충분한 CPU 시간을 확보할 수 있도록 한다.
* 태스크 간의 우선순위 유지를 위해 Xenomai의 우선순위 상속 메커니즘(Priority Inheritance)을 적극적으로 활용한다.

#### 2. 리소스 접근 전략 개선

**뮤텍스(Mutex) 사용 개선**

* 태스크 간의 뮤텍스 사용을 최소화하거나, 뮤텍스 잠금을 최적화하여 경합을 줄이다.
* Xenomai의 실시간 뮤텍스 옵션을 활용하여 우선순위 역전 문제를 방지한다.

**세마포어(Semaphore) 사용**

* 리소스 접근 시, 세마포어를 사용하여 태스크 간의 조화를 유지한다.
* 세마포어의 `wait` 호출 시 타임아웃을 설정하여 데드라인을 놓치는 상황을 방지한다.

#### 3. 고급 트레이싱 기법을 통한 실행 경로 분석

* **Xenomai의 `latency` 테스트 유틸리티**를 사용하여 시스템의 전체적인 스케줄링 지연(latency)을 측정한다.
* **ftrace, LTTng과 같은 사용자 공간 및 커널 공간 트레이싱 도구**를 사용하여 상세한 실행 경로를 분석한다.
* 실행 경로상에서 발생하는 모든 함수 호출과 이벤트를 기록하여 상세한 분석을 수행한다.

#### 트레이싱 기법 예시

**ftrace 사용법**

```bash
$ echo function_graph > /sys/kernel/debug/tracing/current_tracer
$ cat /sys/kernel/debug/tracing/trace_pipe
```

**LTTng 사용법**

```bash
$ lttng create my-session
$ lttng enable-event -k --syscall
$ lttng start
... (시스템 작동)
$ lttng stop
$ lttng view
```

#### 결과

수차례의 디버깅과 최적화 작업을 통해 시스템이 예상대로 동작하도록 개선하였다. 최종적으로, 모든 높은 우선순위 태스크는 데드라인을 놓치지 않고 수행되었으며, 전체 시스템의 실시간 성능이 향상되었다.

* **최종 프로파일러 결과:**

```bash
Task               Avg_exec_time    Max_exec_time    Overruns
--------------------------------------------------------------
Task_1             1.0ms            1.5ms            0
Task_2             7ms              9ms              0
Task_3             0.7ms            1.0ms            0
```

***

복잡한 실시간 시스템의 디버깅은 다각적인 접근이 필요하다. 이번 사례 연구를 통해 다양한 디버깅 및 프로파일링 기법을 활용하여 실시간 성능 문제를 해결할 수 있음을 확인할 수 있었다. 특히 각 태스크의 실행 시간을 정밀하게 분석하고, 리소스 경합을 완화하는 과정이 핵심이었다.
