linux内核堆栈打印方法
dump_stack()
或
__backtrace()
linux应用层堆栈打印方法
int backtrace(void **buffer, int size);
获取当前的调用栈信息,结果存储在buffer中,返回值为栈的深度,参数size限制栈的最大深度,即最大取size步的栈信息。
char **backtrace_symbols(void *const *buffer, int size);
把backtrace获取的栈信息转化为字符串,以字符指针数组的形式返回,参数size限定转换的深度,一般用backtrace调用的返回值。
void backtrace_symbols_fd(void *const *buffer, int size, int fd);
它的功能和backtrace_symbols差不多,只不过它不把转换结果返回给调用方,而是写入fd指定的文件描述符。
示例:
void myfunc3(void)
{
int j, nptrs;
#define SIZE 100
void *buffer[SIZE];
char **strings;
nptrs = backtrace(buffer, SIZE);
printf("backtrace() returned %d addresses\n", nptrs);
/* The call backtrace_symbols_fd(buffer, nptrs, STDOUT_FILENO)
* would produce similar output to the following: */
strings = backtrace_symbols(buffer, nptrs);
if (strings == NULL) {
perror("backtrace_symbols");
exit(EXIT_FAILURE);
}
for (j = 0; j < nptrs; j++)
printf("%s\n", strings[j]);
free(strings);
}
static void /* "static" means don't export the symbol... */
myfunc2(void)
{
myfunc3();
}
void myfunc(int ncalls)
{
if (ncalls > 1)
myfunc(ncalls - 1);
else
myfunc2();
}
int main(int argc,char *argv[])
{
if (argc != 2) {
fprintf(stderr,"%s num-calls\n", argv[0]);
exit(EXIT_FAILURE);
}
myfunc(atoi(argv[1]));
exit(EXIT_SUCCESS);
}
编译:
:cc prog.c -o prog
结果:
:./prog 0
backtrace() returned 6 addresses
./prog() [0x80485a3]
./prog() [0x8048630]
./prog() [0x8048653]
./prog() [0x80486a7]
没输出什么。
加上 -rdynamic:
-rdynamic
Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of “dlopen” or to allow obtaining backtraces from within a program.
重新编译:
cc -rdynamic prog.c -o prog
结果:
./prog 0
backtrace() returned 6 addresses
./prog(myfunc3+0x1f) [0x8048763]
./prog() [0x80487f0]
./prog(myfunc+0x21) [0x8048813]
./prog(main+0x52) [0x8048867]
/lib/libc.so.6(__libc_start_main+0xe6) [0xaf9cc6]
./prog() [0x80486b1]
本文介绍了在Linux环境下,如何分别打印内核层和应用层的调用堆栈信息。通过backtrace系列函数,可以获取并转化栈信息,用于分析程序执行路径。在应用层,需要注意编译时添加-rdynamic选项,以完整显示动态链接的符号信息。
5958

被折叠的 条评论
为什么被折叠?



