정보공간_1

[3기 대전 김재원] Linux Kernel Debugging - Dynamic Probes(2) 본문

IT 놀이터/Elite Member Tech & Talk

[3기 대전 김재원] Linux Kernel Debugging - Dynamic Probes(2)

알 수 없는 사용자 2013. 2. 5. 20:28

안녕하세요! 
대전 멤버십 22-1기 김재원입니다.

Dynamic Probes
1. kprobe        
2. Jprobe        


지난 블로깅내용에 이어 Dynamic Probe를 계속하겠습니다.

지난 사간에는 Dynamic Probe의 가장 기본적인 Kprobe를 알아보았습니다. 이번 시간부터는 Kprobe를 응용한 다양한 기능을 가진 Probe를 알아 보도록 하겠습니다.





Jprobe

Jprobe는 Kprobe를 이용하여 만들어졌습니다. Function의 Entry Point에 삽입된 Kprobe라고 간단히 보면 됩니다. 

Jprobe 구조

Jprobe의 구조체를 살펴 보겠습니다.

Jprobe 구조체

 

Jprobe 구조체는 kprobe 를 가지고 있고 void*인 entry를 가지고 있습니다.

그러면 Jprobe는 어떠한 기능을 위해 만들기 만들어 졌을까요??


Kprobe는 exception context에서 수행됩니다. 그래서 해당 함수에 대한 직접적인 영향을 미치기가 힘듭니다. 

지역변수에 접근하기 위해서는 불가능 하지는 않지만 매우 힘든 과정을 거쳐야 합니다.

그래서 Jprobe는 실행되는 Function의 context에서 실행 되도록 되어 있습니다. 이렇게 실행되는 context에서 실행되면 지역변수에 접근하기가 매우 쉬워집니다.

특히 Jprobe의 가장큰 장점은 Function의 Argument에 접근이 가능합니다. Function의 Argument를 바꾸거나 Debugging하는데 매우 유용합니다.

 

동작원리


동작원리를 살펴보겠습니다.

우선 Jprobe를 register하기 위해 "register_jprobe(struct jprobe *jp)"를 살펴 보겠습니다.


 register_jprobe


register_jprobes를 보게 되면 

arch_deref_entry_point를 이용해 struct jprobe의  entry를 변환하여 addr에 넣고 

kp->kp.pre_handler에 setjmp_pre_handler를 입력하고

kp->kp.break_handler에 longjmp_break_handler를 입력한다음

jp->kp를 register_kprobe로 등록 하게 됩니다.

위 과정을 보면 jprobe에서 조금 수정한뒤 kprobe로 등록하는 과정을 보실 수 있습니다. 가장 중요한 것은 setjmp_pre_handler가 하는 일이라고 할 수 있습니다.


 setjmp_pre_handler

setjmp_pre_handler가 호출되면 호출시점의 레지스터와 스택을 일부 저장하고 exception context에서 벗어나 entry위치부터 다시 실행 되도록 한다. 

(entry위치는 사용자가 임으로 지정한 Function위치이다.) 

entry에서는 원래 함수의 호출한 상황과 같이 만들어 함수의 Argument에 접근 할 수 있도록 한다.

다시 원래 지점으로 돌아 가기 위해서는 jprobe_return();을 실행하여 저장해 두었단 레지스터와 스택을 다시 복구하여 원래 상태로 돌아 가게 된다.


 

예제

이제 실제 실습에 들어가보도록 하겠습니다.

우선 "do_sys_open" 라는 Function을 추적하고 넘어온 Argument의 하나인 filename을 출력 해보도록 하겠습니다.


 Kernel Module

Kprobe와는 다르게 Jprobe는 entry를 작성함으로써 Function의 Argument에 접근 가능 합니다.

entry의 반환형은 없으며 argument의 값은 원래 추적 하는 함수와 같이 해주어야 합니다.

또한 entry의 마지막 지점에 jprobe_return()을 꼭 해주셔야 합니다.

 

결과

위의 코드의 출력 결과를 보면 다음과 같습니다.


  Log 내용

 

로그를 보면 

/etc/hosts,    /etc/ld.so.cache,    /lib/i386-linux-gnu/libc.so.6,     /usr/lib/locale/locale-archive가 읽혀지는 로그를 출력 해볼수가 있습니다.

Jprobe는 Kprobe보다 편리하고 Function의 Argument에 접근 할 수 있다는 장점을 가지고 있습니다.


Jprobe를 이용하여 쉽고 편리하게 Kernel Debugging 하시기 바랍니다!!

----------------------------------------------------------------------------------------------------

출처 :     Linux Kernel Documentation     => Kprobe.txt

http://studyfoss.egloos.com      => F/OSS study