c|__builtin_return_address/_RET_IP_/_THIS_IP_



GCC内建函数 __builtin_return_address http://www.360doc.com/content/12/0828/17/9336047_232846513.shtml
内建函数 __builtin_return_address返回当前函数或其调用者的返回地址,参数LEVEL指定在栈上搜索框架的个数,0表示当前函数的返回地址,1表示当前函数的调用者的返回地址,依此类推。例如:
先举几个内核中使用该内建函数的例子:
printk(KERN_ERR "schedule_timeout: wrong timeout "
438:"value %lx from %p/n", timeout,
439:__builtin_return_address(0));

linux-3.4\arch\arm\mm\ioremap.c中:
void __iomem *
【c|__builtin_return_address/_RET_IP_/_THIS_IP_】__arm_ioremap_pfn(unsigned long pfn, unsigned long offset, size_t size,
unsigned int mtype)
{
return __arm_ioremap_pfn_caller(pfn, offset, size, mtype,
__builtin_return_address(0));
}

在 linux-3.4\net\netfilter\ipvs\ip_vs_conn.c中
pr_err("%s(): request for already hashed, called from %pF\n",
__func__, __builtin_return_address(0));

在 linux-3.4\arch\arm\include\asm\ftrace.h中有下列定义:
#define CALLER_ADDR0 ((unsigned long)__builtin_return_address(0))
#define CALLER_ADDR1 ((unsigned long)return_address(1))
#define CALLER_ADDR2 ((unsigned long)return_address(2))
#define CALLER_ADDR3 ((unsigned long)return_address(3))
#define CALLER_ADDR4 ((unsigned long)return_address(4))
#define CALLER_ADDR5 ((unsigned long)return_address(5))
#define CALLER_ADDR6 ((unsigned long)return_address(6))


__builtin_return_address(LEVEL)函数解释
http://blog.chinaunix.net/uid-26817832-id-3351553.html
1、gcc默认不支持__builtin_return_address(LEVEL)的参数为非0。好像只支持参数为0。
2、__builtin_return_address(0)的含义是,得到当前函数返回地址,即此函数被别的函数调用,然后此函数执行完毕后,返回,所谓返回地址就是那时候的地址。
3、__builtin_return_address(1)的含义是,得到当前函数的调用者的返回地址。注意是调用者的返回地址,而不是函数起始地址。

http://blog.chinaunix.net/uid-25873032-id-383109.html
在当前函数的任何地方调用__builtin_return_address(0)并printk返回值,在运行后得到返回值0xc1234568,再用这个值从目标文件中查找到对应的符号(arm-linux-addr2line 0xc1234568 -e vmlinux -f),此符号即为调用当前函数的调用者的函数名。


_RET_IP_与_THIS_IP_ 在 linux-3.4\include\linux\kernel.h中有这两个宏的定义:
#define _RET_IP_(unsigned long)__builtin_return_address(0)
#define _THIS_IP_({ __label__ __here; __here: (unsigned long)&&__here; })

可看出 _RET_IP_就是使用 __builtin_return_address来实现的,内核中也有例子:
linux-3.4\mm\memblock.c中:
int __init_memblock memblock_free(phys_addr_t base, phys_addr_t size)
{
memblock_dbg("memblock_free: [%#016llx-%#016llx] %pF\n",
(unsigned long long)base,
(unsigned long long)base + size,
(void *)_RET_IP_);

return __memblock_remove(&memblock.reserved, base, size);
}

调试内核的时候,想打印当前进程的地址可使用 _THIS_IP_

还可以使用 dump_stack() 来打印相关的栈。






20140808补充:
GCC提供了两个内置函数用来在运行时取得函数调用栈中的返回地址和框架地址
Built-in Function: void * __builtin_return_address (unsigned int level)
Built-in Function: void * __builtin_frame_address (unsigned int level)

__builtin_return_address的解释可参考:
http://www.ocf.berkeley.edu/~pad/tigcc/doc/html/gnuexts_SEC103___builtin_return_address.html
This function returns the return address of the current function, or of one of its callers. The level argument is number of frames to scan up the call stack. A value of 0 yields the return address of the current function, a value of 1 yields the return address of the caller of the current function, and so forth.

__builtin_frame_address 的解释可参考:
http://www.ocf.berkeley.edu/~pad/tigcc/doc/html/gnuexts_SEC103___builtin_frame_address.html
This function is similar to __builtin_return_address, but it returns the address of the function frame rather than the return address of the function. Calling __builtin_frame_address with a value of 0 yields the frame address of the current function, a value of 1 yields the frame address of the caller of the current function, and so forth.
The frame is the area on the stack which holds local variables and saved registers. The frame address is normally the address of the first word pushed on to the stack by the function. However, the exact definition depends upon the processor and the calling convention.

下面的link里有x86架构下__builtin_return_address的实现,可参考。
http://www.360doc.com/content/12/0828/17/9336047_232846513.shtml

下面的link里有关于__builtin_return_address的一些描述,可参考一下:
http://www.crifan.com/order___builtin_return_address_level/
http://www.haogongju.net/art/2242376



    推荐阅读