주식회사 누리아이티

정보자산의 보안강화를 위한 다계층 인증SW (BaroPAM) 전문기업.

▶ Tuxedo/기술자료

▶ 디버깅

누리아이티 2012. 2. 23. 10:55

   - 코어파일로 작업하기
     코어 파일이 만들어지는 원인은 메모리 참조를 잘못했거나 잘못된 명령어, 버스 에러(bus error), 사용자가 quit 시그널을 발생시킨 경우 등 여러 가지가 있다. 코어파일은 중단된 프로세스의 메모리 이미지를 포함한다.

   - printf() 디버깅 기법
     가장 일반적이고 널리 사용되는 디버깅 기법은 아마 printf() 디버깅일 것이다.
     -DDEBUG 컴파일 옵션을 사용해서 컴파일하면 디버그 메시지를 보여주게 된다.
     이 방법은 개발의 초기 단계에서 아주 일반적으로 사용되는 방법이지만 다음과 같은 단점이 있다.
     1) 새 printf()디버그 라인을 코드에 추가하고 나면 일일이 소스코드를 다시 컴파일해야 한다.
     2) 멀티 쓰레드 어플리케이션을 printf()로 디버깅하려면 매우 복잡한 작업이 된다.
     3) printf()를 많이 호출하므로 어플리케이션의 성능이 저하된다.
     4) DBGMSG 매크로를 너무 많이 사용하면 디버그 메시지 자체가 너무 많아져서 실제 에러를 추적하기가 매우 어렵다.

   - 디버깅 용도로 어플리케이션 준비하기
     어떤 디버거를 사용하더라도, 우선 어플리케이션을 -g 옵션을 사용해서 컴파일하고 최적화 옵션은 사용하지 말아야 한다. 이렇게 하지 않으면 디버거가 어플리케이션 내의 심볼을 해석할 수 없기 때문에, 디버깅과정 중에 변수나 함수를 참조할 수 없다.
     AIX용 C/C++ 컴파일러 최신버전에서 제공하는 유용한 옵션은 다음과 같다.
     -qfullpath  : 디버깅 정보에 소스 파일 전체 경로를 포함한다. 소스 파일 구조가 매우 복잡하고 큰 경우 디버거가 일일이 소스 파일위치를 물어보지 않아도 되므로 유용하다.
     -qlinedebug : 디버깅 정보에서 변수 설명을 제거한다. 최적화한 코드라면 변수설명부분을 제거하는 게 유리한데, 어차피 최적화된 코드라면 변수를 모니터링해도 잘못된 정보만을 보여주기 때문이다. 이 옵션을 사용하면 디버깅 정보부분의 크기를 많이 줄여주므로 특히 C++ 프로그램의 경우에 유리하다.
     -qdbxextra  : 프로그램내의 모든 심볼의 참조여부에 관계없이 디버깅 정보를 모두 포함한다. 보통의 경우에는 참조하는 심볼에 대한 디버깅 정보만 포함한다. 이 옵션을 사용하면 경과로 생기는 실행파일의 크기가 매우 커진다.
     어플리케이션을 컴파일할 때 디버깅 정보를 포함하도록 하면 실행파일의 크기가 매우 커질 수 있다. 특히 C++ 같은 경우는 거의 10배 이상으로 커진다. -qlinedebug를 잘 사용하고 필요 없는 부분에서 디버깅 정보를 제거하면 크기를 많이 줄일 수 있다.

   - dbx 사용법
     심볼릭 디버거 dbx는 AIX를 포함하여 많은 UNIX에서 가장 널리 사용되는 디버거이다. 어플리케이션에 발생한 문제를 디버깅하기 위해 dbx는 다음과 같은 기능을 제공한다.
     1) 오브젝트와 코어 파일을 검사한다.
     2) 프로그램을 수행하는 환경을 커스터마이징할 수 있다.
     3) 브레이크 포인트를 설정한다.
     4) 프로그램의 로직을 따라가볼 수 있다.
     5) 심볼릭 변수를 관리할 수 있다.
    
     어플리케이션이 비정상으로 종료되고 코어 파일을 생성하면 다음과 같이 dbx를 사용한다.
     $dbx ObjectFile CoreFile
     dbx 세션을 종료하려면 dbx 서브 명령어인 quit 을 사용하시오.
     (dbx) quit
     이미 수행되고 있는 프로세스가 무한루프를 돌고 있는지 알아보기 위해 수행되고 있는 도중에 프로세스를 디버깅해야 할 경우가 있다. 이 경우에는 -a 옵션을 사용하여 프로세스의 PID를 지정하여 이를 dbx 세션에 붙이는 방법을 사용한다.
     $ dbx -a 25952
     (dbx) quit
     서브 명령어 프롬프트에서 quit을 입력하면 dbx 세션뿐만 아니라 프로세스도 같이 종료된다. 프로세스는 종료하지 않고 dbx세션만 끝내려면 detach 서브 명령어를 사용한다.

     dbx 명령은 다음과 같은 순서로 .dbxinit 초기 환경설정 파일을 읽는다.
     1) 현재 디렉토리
     2) 사용자 홈 디렉토리
     만약 현재 디렉토리에 .dbxinit 파일이 있으면 사용자 홈 디렉토리까지 읽지 않는다. 물론 -c 옵션을 사용하여 환경설정파일을 지정해 줄 수 있다.
     자주 사용하는 서브명령어나 매크로를 알리아스로 정의하면 dbx 세션을 편리하게 커스터마이즈할 수 있다.
     dbx 세션을 이미 시작하고 난 뒤라면 다음 서브 명령어를 사용하여 환경설정 파일을 읽어올 수 있다.
     (dbx) source /home/ausres01/.dbxinit

   - truss로 디버깅하기
     truss명령은 라이브러리를 조사하여 프로세스에서 사용한 시스템 콜과 시그널 활동을 검사한다. truss 명령을 사용하여 프로세스에서 수행한 모든 시스템 콜과 시스템 콜로 넘긴 파라미터, 그리고 시스템 콜에서 반환한 데이터나 에러 값을 조사할 수 있다. 따라서 어플리케이션이 AIX OS에 요청한 사항과 결과를 바로 볼 수 있다.

   - trace 사용하기
     trace는 시스템 모니터링 서비스이며 수많은 이벤트 중에서 필요한 정보만을 뽑아낼 수 있도록 한다. trace는 미리 정의한 시스템 이벤트 집합에 따라 시스템 활동에 대한 자세한 정보를 제공한다. 어플리케이션의 수행되는 과정을 검사하기 위해 trace 훅을 어플리케이션에 추가할 수 있고, 이런 경우 코어 파일 없이도 디버깅이 가능하다.