参考博客:Linux打印函数调用栈_sesshoumaru66的博客-CSDN博客_linux打印函数调用栈
很多时候,我们需要了解栈的调用信息,特别是有一些使用函数指针的回调函数,有栈的调用信息,更方便分析程序运行流程。
Linux内核里面,可以使用dump_stack()函数。该方法在我的另一篇博客有介绍。
Linux 应用程序实现如下:
环境背景:我们有个库函数,有很多程序调用,我们想知道有哪些程序在调用,我们可以通过栈信息来反向关联。
库代码:
#include <stdio.h>
#include <execinfo.h>
#define MAX_DEPTH 20
void PrintfStackFunName(void)
{
void *buff[MAX_DEPTH] = { 0 };
unsigned int depth = backtrace(buff, MAX_DEPTH);
char **funName = backtrace_symbols(buff, depth);
for (int i = 0; i < MAX_DEPTH; i++) {
if (i >= depth) {
break;
}
printf("i = %d, func = %s\n", i, funName[i]);
}
}
void lib_func()
{
printf("%s %s %d.\n", __FILE__, __func__, __LINE__);
PrintfStackFunName();
}
库编译命令:
gcc -o dump_stack.o -c dump_stack.c -shared -fPIC
ar -r libdump_stack.a dump_stack.o
main程序代码:
#include <stdio.h>
#include "dump_stack.h"
void func4(void)
{
printf("%s %s %d.\n", __FILE__, __func__, __LINE__);
lib_func();
}
void func3(void)
{
printf("%s %s %d.\n", __FILE__, __func__, __LINE__);
func4();
}
void func2(void)
{
printf("%s %s %d.\n", __FILE__, __func__, __LINE__);
func3();
}
void func1(void)
{
printf("%s %s %d.\n", __FILE__, __func__, __LINE__);
func2();
}
int main(void)
{
func1();
return 0;
}
main程序编译代码:
gcc main.c -L./ -ldump_stack -rdynamic
//注:选项 -rdynamic 用来通知链接器将所有符号添加到动态符号表中。不加这个选项,打印出来的堆栈只有地址没有函数接口
执行程序及输出信息:
qidong.liu@cqrnd01:~/lqd/c/lib/test_lib_dump_stack$ ./a.out
main.c func1 25.
main.c func2 19.
main.c func3 13.
main.c func4 7.
dump_stack.c lib_func 23.
i = 0, func = ./a.out(PrintfStackFunName+0x45) [0x400ab8]
i = 1, func = ./a.out(lib_func+0x2d) [0x400b83]
i = 2, func = ./a.out(func4+0x2c) [0x4009e2]
i = 3, func = ./a.out(func3+0x27) [0x400a0c]
i = 4, func = ./a.out(func2+0x27) [0x400a36]
i = 5, func = ./a.out(func1+0x27) [0x400a60]
i = 6, func = ./a.out(main+0x9) [0x400a6c]
i = 7, func = /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf0) [0x7f98e3034840]
i = 8, func = ./a.out(_start+0x29) [0x4008e9]
qidong.liu@cqrnd01:~/lqd/c/lib/test_lib_dump_stack$