임베디드 환경에서의 개발이란 항상 리소스가 부족하다. 그러한 관계로 타겟 보드 자체에서 GDB같은 툴을 사용하여 디버깅할 수 있는 여건이 되지 않는 경우가 대부분이다. 통상적으로 Host에서 Remote Debugging을 할 수 있다고 하지만 현실적으로 네트웍을 통한 디버깅이라는 것이 매우 힘들고 실현 가능하지 않는 경우가 대부분이다. 그렇다면 임베디드 디버깅을 어떻게 하는가?
1. printf()를 사용한다. 대부분의 타겟개발 환경의 시작은 시리얼포트를 통해서 하게 되는데 시리얼 포트를 통하여 debug 메시지를 출력하는 방법이다. 가장 고전적이고 여전히 유효하며 최후의 수단이자 가장 강력한 방법이다.
2. core dump를 활용한다. 특정 시점에서의 각 변수의 값이나 스택의 상태등 모든 것을 알고 싶을때 printf로 하기에는 너무 힘들다. 이럴때는 core dump를 만들어서 사용한다. 어떻게? 강제적으로 segment fault등을 만들면 된다. core dump가 필요한 시점에
*((char *)0) = 0;
같은 코드를 넣어서 강제로 segment fault를 만드는 것이다. core dump가 있으면 Remote debugging용 gdb를 이용하여 core dump를 로드하여 fault시점의 모든 변수와 Call stack을 분석할 수 있다. source는 -g 옵션으로 컴파일 해야 함은 물론이다. 꼭 알아야 하는 핵심 gdb 명령은 다음과 같다.
bt: 스택 프레임을 보여준다.
frame : n frame상태로 이동한다.
info locals: 로컬 변수들을 표시한다.
p : 변수 값을 표시한다.(수식도 가능)
3. 타겟의 glibc가 backtrace_symbol()같은 훌륭한 함수를 구현해 두었다면 적극 활용한다. backtrace_symbol을 실행중 언제라도 call stack을 보여주는 함수다. glibc포팅이 제대로 안되면 지원 안되는 경우가 있으므로 정확히 동작하는지 테스트코드를 만들어 보고 사용하는 것이 좋다.