사이트맵 보기

활용사례

TRACE32를 이용한 디버깅 방법 공유

작성일

작성자 김태흥

조회수 10740

첨부파일

Android project를 진행 하면서 T32를 이용해서 critical issu를 해결한 경험과 제가 사용하는 몇가지 know-how를 소개 합니다.


1. 모델 진행시 나온 critical issue 해결 경험
Android froyo 모델 개발때 상황으로 내부 QM마지막 차수 였고 갑잡스런 커널 패닉으로 인해 출시가 지연되느냐 마느냐 하는 critical issue 였습니다.
QM으로 부터 해당 이슈 로그를 전달 받고 살펴 보면 kernel이 사용하는 slab영역이 깨져서 커널 패닉이 발생 한것으로 분석이 되는데 이넘이 왜 깨지는지를 알수가 없는 상황이 였습니다. 이상황에서 jtag을 이용해서 잡아야 겠다는 생각에 다음과 같이 재현 하였습니다. 일단 재현이 되면 커널 패닉이 나기때문에 target이 리셋되는 상황입니다. 이렇게 되면 정확한 실시간 디버깅이 안되기때문에 2가지 디버깅 코드를 추가 했습니다.



첫째 문제 발생시 slab이 깨지게 되면 slab allocator는 bug()를 이용해서 의도적인 패닉을 발생 시기키기 때문에 bug()함수전에 무한루프를 잡게 추가 했습니다.



둘째 재현 되어 무한루프에 걸리게 되면 일정시간후 watchdog kick을 안해주면 폰이 reset되기때문에 폰이 부팅하면서 watchdog을 disable하게 하였습니다.


이렇게 두가지 코드를 추가 하고 jtag을 hw적으로만 연결하고 열심히 재현 하였고 결국 2틀만에 무한루프에 잡히게 되었습니다. 이때 t32 application을 실행해서 attach한후 stop을 해보면 정확히 무한 루프 코드에 pc값이 잡혀 있는것을 보았고 너무 기뻤습니다. ㅋㅋ
그리고 깨진 slab영역을 d.dump라는 명령을 통해 메모리를 보니 어디서 많이 보았던 file path가 적혀 있었습니다. 다름아닌 android에서 wakelock을 잡기 위해 커널쪽에 들어오게 되는데 어느 모듈이 wakelock을 잡는지 적어 놓는 패스 였습니다.
그리고 wakelock드라이버를 보니 user space넘어오는 패스를 메모리에 copy하게 되어 있는데 포인트 연산으로 메모리에 copy하게 되어 있더군요 결국 이넘이 overflow가 되서 기존 slab할당 해놓은 곳으로 치고 들어왔던거였습니다.


2. 제가 알고 있는 know-how


- 일반적으로 프로젝트 초창기 디버깅 환경 구축을 위해서 MDS쪽 기술 지원을 받으면서 같이 구축 하게 됩니다. 그럴 경우 리눅스 커널은 MMU켜진 후 보다 구체적으로는 c code level인 start_kernel부터 디버깅 할수 있게 환경을 구축 하게 됩니다. 하지만 제경우는 보드 bring up을 하다보니 start_kernel전단 혹은 MMU가 켜지기 전에 디버깅이 필요한 경우가 있습니다. 이럴때는 기존 구축한 디버깅 환경에서는 불가능 한 상황으로 다음과 같이 해서 해당 상황의 디버깅을 합니다.
일단 Bootloader에서 멈춘후 d.load.elf 명령을 통해서 리눅스 커널 심볼인 vmlinux를 올립니다. 그리고 다음과 같은 명령으로 심볼을 shift합니다.
y.reloc.shift 0xc0200000 그리고 원하는 kernel start code에 break를 걸고 go
그러면 원하는 곳에 target이 멈추게 되고 신나게 디버깅 ~~
여기서 y.reloc.shift 하는 이유는 MMU가 켜지기 전이고 우리 심벌은 모두 Virtual address로 mapping되어 있기 때문에 심벌을 shift시켜야 원하는곳에 정확히 위치 하게 됩니다.



- break point관련 해서 저는 memory쪽에 read/write break point를 자주 이용하게 됩니다. 소스 분석이 안된 상황에서 특정 메모리에 어떤 넘이 자꾸 변경하는지 보기 위해서는 read/write break가 아주 유용합니다.
특정 메모리에 read/write break걸고 target이 stop되면 v.f로 어떤넘이 치고 들어 왔는지 보면 금방 이슈가 잡히더라고요....



- simulator 이용한 방법
이방법은 실시간 디버깅 방법이 아니라 이미 이슈가 발생 했고 램덤프데이타가 있을때 디버깅 하는 방법입니다.(주로 QM부서에서 제공 하는 덤프 데이타를 가지고 분석하는 방법-리눅스 커널쪽)
지금까지는 리눅스 커널쪽 크래쉬 상황에서 램덤프 가지고 자동 시뮬레이션 시키는 방법을 사용 하지 않았는데요 제경우는 다음과 같이 해서 자동 시뮬레이션 되도록 하였습니다. 현재 실제 모델 개발시 이용 하고 있고요
이방법을 사용하기 위해서는 1메가 정도의 메모리 공간이 필요 합니다.
즉 커널이 사용하는 메모리에 1메가를 떼어내서 패닉이 났을때 panic이 난 상황에 cpu context를 해당 영역에 저장 하게 합니다. 그리고 시뮬레이션을 위한 자동 복구 cmm을 만듭니다. 자동 복구 cmm은 다음과 같이 만듭니다.
첫째 d.save.binary command를 이용해서 확보된 덤프를 올립니다.
둘째 미리 할당 해놓은 메모리영역에서 CPU context저장 되어 있기때문에 해당  메모리 영역에서 register 값들을 가져와 register 설정을 해주게 합니다
이렇게 하면 crash상황의 리눅스 커널 context를 정확히 복원 할 수 있습니다.


 

고객문의 기술지원/
데모/
SW요청
031-627-
3116