Software 엔지니어라면 디버깅의 중요성을 실감하실 것입니다. C/C++ 개발자는 메모리를 직접 제어하기 때문에 힘들고, 임베디드 엔지니어라면 하드웨어가 어떻게 동작할 지 모르기 때문에 더더욱 신경써서 에러처리를 해 주어야 합니다. 안그럼 밥줄이 끊어져 버릴 수 있습니다. 밥은 먹고 살아야 하기에...

디버깅을 하는 방식은 크게 두 가지로 나뉩니다. 개발툴에서 지원하는 디버깅 기능을 사용할 수 도 있고, 전통적으로 내려오는 printf() 신공이 그것입니다. 바로 지금 이야기하고자 하는 것은 printf()신공을 효율적으로 사용하기 위한 방법입니다. 비슷한 것으로는 MFC의 TRACE 매크로나 MessageBox 류의 함수들이 있습니다.

먼저 printf()의 단점부터 이야기 하자면:
타이핑을 많이 쳐야하니 힘들고,
에러가 한번에 안나오면 [코딩 -> 빌드 -> 실행 -> 코딩 -> 빌드 -> 실행] 이런식의 무한반복을 해야하니 힘들고,
나중에 다 찾아서 지워야 하니 더 힘들고....
힘들고...
힘들고.....
힘들고....... 먹고살기 정말 힘드네요.


반면에 장점은:
디버깅 툴이 없는 상황에서도,
멀티쓰레드 환경에서 Dead lock 을 잡을 때도,
임베디드 환경에서와 같이 실시간성이 중요한 곳에서도 사용하실 수 있습니다.
정말 놀라운 능력이죠.


아래에 제가 사용하는 코드를 첨부합니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#define USE_LOCAL_DEBUG
#define USE_LOCAL_TRACE

#if defined(USE_LOCAL_DEBUG) || defined(USE_LOCAL_TRACE)
#define DEBUG_NAME "* [Module Name]"
#endif

#ifdef USE_LOCAL_DEBUG
#define local_debug(...) do{printf(DEBUG_NAME " " __VA_ARGS__);}while(0)
#else
#define local_debug(...) do{}while(0)
#endif

#ifdef USE_LOCAL_TRACE
#define local_trace(...) do{printf(DEBUG_NAME " "); printf("(%d Line)",__LINE__); printf(" "__VA_ARGS__);}while(0)
#else
#define local_trace(...) do{}while(0)
#endif

이 코드는 .c 혹은 .cpp 파일의 상단에 복사해 놓고 사용하라고 만들었습니다. 절대! Never! 헤더파일에 넣으면 안됩니다. 컴파일러가 싫어합니다. 중복정의 어쩌구하면서 경고를 내놓을 뿐더러 원하는대로 동작도 하지 않을 것입니다.

다시한번 강조하지만 .c 혹은 .cpp 파일에 넣고 쓰세요.

사용법은 간단합니다.
  1. DEBUG_NAME 매크로에 모듈 이름을 적는다.
  2. printf 대신 local_debug와 local_trace를 사용한다.
  3. 이제 로그를 보고싶지 않으면 첫 번째 줄과 두 번째 줄을 주석처리한다.
  4. 나중에 다시 보고싶으면 주석을 해제한다.

참 쉽죠잉?




+ Recent posts