사이트맵 보기

활용사례

TRACE32 를 이용한 Process Freezing Debuging 기법

작성일

작성자 이원건

조회수 6692

첨부파일

안녕하세요.

결론부터 이야기 하면..
chip set(AP) 내부에서 ram 에서 L1 cache 로 arm instruction 을 복사할때 간헐적으로 누락되는 문제가 있었습니다.

이러한 문제는 trace32 가 아니면 분석이 거의 불가능한 문제 입니다.
제가 고안해낸 process freezing debugging 기법과 trace32 의 강력한 기능을 결합한 디버깅 know-how를 공유하고자 합니다.

이렇게 어려운 문제도 해결 할 수 있도록 도와준 trace32 는 저의 개발인생의 보물이자 저의 힘 이라고 생각합니다.


* process freezing debugging 기법은 다음과 같은 문제 상황에서 유용합니다.

   1. 문제현상이 발생하면 device 의 상태가 변경되어 debugging infomation 을 구하기 어려운 경우
   2. 매우 적은 확율로 재현되는 문제
   3. 단순 code level debugging 으로 분석되지 않는 문제.

* 참고 : linux base 의 system 입니다.



1. 문제 현상 : device power off중 불특정 application 들이 SIGSEGV 와 SIGILL 이 발생하며 비정상 종료 함.
 - 문제 발생 시료를 다시 실행하면 문제 발생하지 않음




2. 문제 시료를 trace32 로 dump 를 떠서 죽은 부분의 ARM instruction 을 검사
 - ram의 data 와 연관된 arm asm instruction(push/pop 이나 STR/LSD등) 이 아닌 cache 만 사용하는 연산에서도  SIGLL 이 발생하며 죽은경우가 있음
 - 문제 발생 이후 device가 power off 되어 버려서 debuging 이 불가능 함.




3. trace 를 사용한 분석

 1) SIGILL 이나 SIGSEGV interrupt 가 발생했을때 process freezing 시키도록 handler 수정
  ** process freezing 방법 **
  -> system interrupt handler 에 h/w s/w watchdog disable 후 무한 loop 수행함.
  -> 문제가 발생하였을때 무한 loop 에 빠져서 다음 sequence 로 넘어가지 않으므로 문제가 발생한 process 의 정보를 그대로 보존한 debugging semple 을 얻을 수 있음.
  -> 문제가 발생한 시점의 arm register 를 얻을 수 있어서 이후 debugging 의 모든 실마리를 재공해 줌.
(arm register value, neon state, sequence 진행으로 인해 값이 변경되지 않은 문제상태 그대로의 stack, running process info, MMU, L1 / L2 cache, sysmmu, interrupt handler 등..)

 2) 문제가 발생한 이후 system interroup handler 에서 freezing 된 상태로 trace32 연결함 -> 이후 trace32 의 강력한 core debugging 기능을 마음껏 사용 가능.

 3) Trace32 에서 Process debugging 기능을 사용해서 동작중인 application 을 symbol mapping 함.

 4) interrupt handler 의 param 중 sigcontext 를 분석하여 ARM register 복원

 struct sigcontext {
  unsigned long trap_no;      // 0000000E
  unsigned long error_code;   // 00000005
  unsigned long oldmask;      // 00000005
  
  unsigned long arm_r0;       // 2A0912F0
  unsigned long arm_r1;       // 00000000
  unsigned long arm_r2;       // 0000006C
  unsigned long arm_r3;       // 00000070
  unsigned long arm_r4;       // 2A0912F0
  unsigned long arm_r5;       // BEF8CAF4
  unsigned long arm_r6;       // 6A08C7C8
  unsigned long arm_r7;       // 00000000
  unsigned long arm_r8;       // 2A046F18
  unsigned long arm_r9;       // 00000000
  unsigned long arm_r10;      // 00000000
  
  unsigned long arm_fp;       // BEF8C97C
  unsigned long arm_ip;       // 40366248
  unsigned long arm_sp;       // BEF8C960
  unsigned long arm_lr;       // 402AEAF4
  unsigned long arm_pc;       // 40036924 -> 문제가 발생한 ARM instruction address
  unsigned long arm_cpsr;     // 20000010
  unsigned long fault_address; // 6A08C838 -> access fail address
 };



 5) 복원한 ARM register 를 기반으로 문제 발생때 실행된 code address 와 access 하다가 fail 발생한 address 를 찾음

  < 마지막 instruction >
  ldr r1, [r6, r3]
  해석 : r1 = *(r6 + r3)


  r6 + r3 = 0x6A08C838 // 맵핑되어 있지 않은 주소를 접근하다 SIGILL 이나 SIGSEGV 발생 -> 비정상 동작시에만 저 값이 발생함.

 6) ARM instruction 을 문제가 발생한 지점부터 arm asm 을 역 계산(steck 풀기)하면서 문제 잘못된 address 에 접근한 원인 분석
  ->결과 :  code area 에서 전단계 함수에서 문제 발생 함수로 bl 을 이용해 jump 한 이후 최초 3개의 arm instruction 이 수행되지 않았을때 문제가 발생한 fail address 값이 생성됨.




4. 문제 원인 분석 완료.
 arm instruction 이 수행되기 위해서는 일반적으로 다음의 과정을 거침
  i. code instruction 수행
  ii. 아직 ram 에 road 되지 않은 operation area 도달
  iii. hit 발생하여 nand 에서 ram 으로 code 영역 복사
  iiii. L1 cache -> L2 cache를 통해서 cpu 에 적재됨

code 가 수행될때 trace32 를 이용하여 ram 에서 L1 cache 로 복사된 메모리를 dump 해서 비교함



 문제 발생시 nand 에서 ram 으로 정상적으로 arm instruction 이 복사 되었으나 L1 cache 로 복사중 누락이 발생하는 문제임


 -> chip set 사에 불량 수정 요청함 : 디버깅 종료


감사합니다.
추가 문의 사항은 제 메일 및 운영중인 블로그 http://decdream.tistory.com/로 연락 바랍니다.

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