본문 바로가기

[Debugging] Tips

[리눅스커널] 디버깅: TRACE32: 모듈 타입 드라이버 심벌(*.ko)을 로딩해 깨진 콜 스택 복원

소개
 
실전 디버깅을 하다보면, 종종 모듈 타입 디바이스 드라이버에서 크래시가 발생할 때가 있습니다.
크래시가 발생하면 먼저 어떤 콜 스택인지 파악하는 경우가 많습니다. 문제는 이 때 TRACE32로 콜 스택 복원을 시도해도 제대로 콜 스택이 출력되지 않는다는 사실입니다.
 
그 이유는 무엇일까요? 바로 모듈 타입 드라이버의 심벌 정보가 없기 때문입니다.
이번 포스트에서는 TRACE32로 모듈 타입 디바이스 드라이버의 심벌을 로딩하는 방법을 소개합니다.
 
 
TRACE32에서 드라이버 모듈 로딩하기
 
아래 스크린 샷은 Arm64 아키텍처의 함수 호출 규약에 따라 레지스터를 세팅 한 후 출력되는 콜 스택입니다.
 
 
 
el1_dbg 라는 레이블이 보이니 BUG() 매크로 함수를 호출해 크래시가 발생한 듯합니다. 그런데 002번째 줄을 보면 이상한 주소만 보이지 함수의 심벌 정보가 보이지 않습니다. 콜 스택이 깨져 보일 때의 화면입니다.
 
이 상황에서 디바이스 드라이버 모듈을 로딩해 제대로 콜 스택을 출력하는 방법을 설명드리겠습니다.
 
TRACE32에서 모듈 파일 로딩하기
 
먼저, 다음 화면과 같이 TRACE32 메뉴 중에 'Linux > Display Modules'을 선택합니다.
 
 
 
그럼, 2개의 디바이스 드라이버 모듈이 보일 것입니다. 이 중 첫 번째 모듈을 선택한 다음에, Load Module Symbols을 선택합니다.
 

 
그 다음에는 모듈로 생성된 디바이스 드라이버 *.ko 파일을 지정하라는 팝업이 출력됩니다.
이 때 *.ko 파일을 선택합니다.
 

 
 
 
제대로 복원된 콜 스택 확인하기
 
모듈 파일을 로딩하니 제대로 콜 스택이 출력됩니다.
 

 
 
콜 스택을 보니 대략 다음과 같은 정보를 확인할 수 있습니다.
 
    * 'insmod' 명령어를 실행해 모듈 타입 디바이스 드라이버가 설치되는 과정이다. 
    * init_module() 함수에서 BUG() 함수를 실행해 커널 패닉이 발생했다.
 
위와 같은 콜 스택으로 모듈식 드라이버가 크래시가 발생하는 경우는 크게 2가지로 분류될 수 있습니다. 
 
   * 드라이버 모듈을 빌드할 때 컨피그가 제대로 설정돼 있지 않음 
   *.ko 파일에 시그니처(Signature)가 제대로 포함돼 있지 않음
 
보통 커널 로그에서 에러 정보를 출력해주니 이 정보를 파악해서 후속 조치를 취하면, 문제는 바로 해결됩니다.
 
끝맺음
 
리눅스 시스템의 구성하는 방식에 따라 다르지만, 어떤 시스템에서는 상당히 많은 모듈 타입 드라이버를 사용해 드라이버가 실행됩니다. 하나의 업체가 커널 드라이버를 책임지는게 아니라, 여러 드라이버 업체가 개발한 드라이버를 동적으로 로딩하는 프로젝트가 있죠.
 
이 때 활용하면 좋은 디버깅 팁이니, 잘 활용하셔서 즐겁게 디버깅하시길 빕니다.
 
Happy, Debugging!