# 1. 하드웨어 레벨 GDB 디버깅 및 하드폴트(HardFault) 트러블슈팅

# 1. 하드웨어 레벨 GDB 디버깅 및 하드폴트(HardFault) 트러블슈팅

아무리 코딩을 잘해도 기체를 공중에 띄우는 순간, “삐-삐-삐” 하는 단말마의 버저음과 함께 픽스호크 보드의 빨간 LED가 격렬하게 점멸하며 기체가 땅으로 곤두박질치는 순간을 피할 수 없다. 콘솔에는 공포의 “HardFault Exception” 텍스트 한 줄만 남긴 채 마이크로컨트롤러가 즉사해 버린다.
단순 printf 방식의 로깅으로는 절대 추적 단서조차 잡을 수 없는 이 시스템 극심층부의 패닉 데드를 부검(Autopsy)하기 위해서는 리눅스의 GDB와 외부 하드웨어 프로브(Probe)를 동원한 침습적 디버깅(Invasive Debugging) 아키텍처가 필수적이다.

하드웨어 디버그 프로브(J-Link / ST-Link)의 물리적 바인딩
마이크로컨트롤러 코어가 널 포인터(Null Pointer) 역참조나 배열 오버플로우로 인해 허용되지 않은 메모리 주소(Invalid Address)를 터치하는 순간, ARM Cortex-M 코어는 방어 기제로 하드폴트 인터럽트를 발생시키고 시스템을 패닉 상태에 빠트린다. 이때 통상적인 USB 케이블 하나로는 죽어버린 칩의 내부 레지스터를 들여다볼 방법이 없다.

이 장벽을 뚫기 위해서는 픽스호크 보드의 구석에 숨겨져 있는 디버그 포트(Debug Port) 플라스틱 커넥터에 J-LinkST-Link 같은 초소형 디버깅 장비를 물리적으로 꽂아 넣고, 이를 호스트 PC에 USB로 연결해야 한다. 이 하드웨어 프로브(Probe) 장비들은 JTAG 혹은 SWD(Serial Wire Debug) 핀 통신 프로필을 사용해 마이크로컨트롤러의 심장부(레지스터와 RAM)에 물리적 고속도로를 거머쥐고 직접 난입한다. CPU가 멈춰버렸든 코마 상태든 강제로 멱살을 잡고 메모리 블록을 덤프(Dump)할 수 있다.

OpenOCD와 GDB 아키텍처 연쇄 시스템
물리적 프로브만 연결했다고 디버깅이 되는 것은 아니다. 호스트 PC에서 복잡한 통신 역어셈블리 체인을 가동해야 한다.

  1. OpenOCD 데몬 백그라운드 발동: 리눅스 데스크톱 셸에서 하드웨어 장비(J-Link 등)와 통신 포맷을 번역해 주는 브리지 서버 프로토콜인 OpenOCD를 실행시킨다. 이 녀석이 포트 넘버 3333을 열고 스탠바이에 들어간다.
  2. GDB 타겟팅 및 심볼 로드: 개발자는 다른 터미널을 열고 앞서 15.6장에서 컴파일 시 남겨두었던, 수십 MB에 달하는 원본 디버그 맵이 꽉 찬 px4_fmu-vX_default.elf 파일을 물고 arm-none-eabi-gdb 터미널을 진입시킨다.
  3. 원격 포인터 체결(target remote localhost:3333): GDB 명령어 창에 타겟 조준 명령을 꽂아 넣는 순간, GDB(소프트웨어 진단 툴) -> OpenOCD(통신 브리지) -> J-Link(하드웨어 프로브) -> Pixhawk CPU(타겟) 로 이어지는 거대한 해킹 와이어가 연결된다.
  4. 백트레이스(bt) 추적: 이 상태에서 GDB 프롬프트에 bt (Backtrace) 명령어를 발사하면, 레지스터 캐시를 역분해하여 기체가 뻗어버린 정확한 소스코드의 c++ 파일 이름과 줄 번호(Line Number), 그리고 그 직전에 어떤 함수들이 호출 계층을 타고 들어갔는지(Call Stack)를 터미널 화면 가득히 증명성 있게 토해낸다.

이 극한의 GDB 디버깅 사슬 체계를 마스터한 자만이, 하늘 위에서 터져버리는 커스텀 제어 루저 모듈의 하드폴트 악몽을 물리적으로 집도하고 치료해 낼 수 있는 마스터 급(Master Class) 자격을 부여받는다.