Posts Tagged ‘Programming’

소프트웨어 크리에이티비티 2.0

월요일, 5월 25th, 2009

http://jhrogue.blogspot.com/2009/05/20.html

소개받은책.

살까나

함수의 리턴 주소 알아내기

월요일, 3월 23rd, 2009

프로파일링이나 함수 래핑으로 lock등의 작업을 가로채서 로깅할 때 호출한 쪽의 PC값을 알고 싶을 경우가 있습니다.

현재실행되는 함수 입장에서 보면 리턴 주소이죠

이 때 쓸 수 있는 함수가 gcc의 builtin함수로 __builtin_return_address() 입니다.

__builtin_return_address(level)

여기서 level은 call stack 에서 몇번째를 리턴할 것인지에 대한 값입니다.

__builtin_return_address(0) 하면 현재함수의 리턴주소가 나옵니다.

__builtin_return_address(1) 하면 나를 호출한 함수의 리턴주소가 나옵니다…

예제 코드를 짜봤습니다.

#include <stdio.h>
#include <stdlib.h>

int my_func1()
{
    void *addr;
    addr =
__builtin_return_address(0);
    printf(”1’s caller %p\n”,addr);
    printf(”hello 1\n”);
}
int my_func0()
{
    void *addr;
    printf(”hello 0\n”);
    addr = __builtin_return_address(0);
    printf(”0’s caller %p\n”,addr);
    my_func1();
}

int main(void)
{
    printf(”backtrace test\n”);
    printf(”main: %p\n”, (void *)main);
    printf(”my_func0: %p\n”, (void *)my_func0);
    printf(”my_func1: %p\n”, (void *)my_func1);
    my_func0();
    return 0;
}

 

이 소스코드를 컴파일해서 objdump해보면

080483d1 <my_func0>:

80483fc:   e8 a3 ff ff ff          call   80483a4 <my_func1>
8048401:   c9                      leave
8048402:   c3                      ret

08048403 <main>:

804845c:   e8 70 ff ff ff          call   80483d1 <my_func0>
8048461:   b8 00 00 00 00          mov    $0×0,%eax

이와 같이 호출하게 되어있고

실행해보면

backtrace test
main: 0×8048403
my_func0: 0×80483d1
my_func1: 0×80483a4
hello 0
0’s caller 0×8048461
1’s caller 0×8048401
hello 1

이렇게 나옵니다. call 바로 다음 주소–리턴 주소가 나오지요.

이외에도 몇가지 builtin함수들이 있습니다.

예를 들어 __builtin_frame_address(level)은 프레임 포인터를 반환합니다.

 

관련 포스트 :

gcc 컴파일 옵션으로 커스텀 프로파일 해서 실행 트레이스 뽑기