订阅
纠错
加入自媒体

linux:如何查看函数被哪些函数调用过?

2021-03-25 14:12
一口Linux
关注


#if 0
   char ** stacktrace = backtrace_symbols(array, stack_num);

   for (int i = 0; i < stack_num; ++i)
   {
       printf("%s", stacktrace[i]);
   }
   free(stacktrace);
#endif

void fun1()

   printf("stackstrace begin:");
   print_stacktrace();

void fun2()

   fun1();

void fun3()

   fun2();

int main()

   fun3();

编译运行gcc编译时加上-rdynamic参数,通知链接器支持函数名功能(不加-rdynamic参数则无函数名打印):

gcc 123.c -o run -rdynamic -g

执行结果:

4. 补充 address2line

同一个函数可以在代码中多个地方调用,如果我们只是知道函数,要想知道在哪里调用了该函数,可以通过address2line命令来完成,我们用第2步中编译出来的test2来做实验(address2line的-f选项可以打出函数名, -C选项也可以demangle):

address2line

三、内核代码中如何打印函数栈?

在Linux内核中提供了一个可以打印出内核调用堆栈的函数 dump_stack()。

该函数在我们调试内核的过程中可以打印出函数调用关系,该函数可以帮助我们进行内核调试,以及让我们了解内核的调用关系。

1. 头文件

该函数头文件为:

#include <asm/ptrace.h>

使用方式:

直接在想要查看的函数中添加

dump_stack();

2. 举例

测试代码如下:hello.c

 1 #include <linux/init.h>
 2 #include <linux/module.h>
 3 #include <asm/ptrace.h>
 4
 6 MODULE_LICENSE("GPL");
 7 MODULE_AUTHOR("PD");
 8 void aaa(int a);
 9 void bbb(int b);
10 void ccc(int c);
11
14 void ccc(int c)
15 {
16     printk(KERN_SOH"cccc ");
17     dump_stack();
18     printk("c is %d",c);
19 }
20 void bbb(int b)
21 {
22     int c = b + 10;
23     printk(KERN_SOH"bbbb ");
24     ccc(c);
25 }
26 void aaa(int a)
27 {
28     int b = a + 10;
29     printk(KERN_SOH"aaaa ");
30     bbb(b);
31 }
32
34 static int hello_init(void)
35 {
36     int a = 10;                                                                
37
38     aaa(a);
39     printk(KERN_SOH"hello_init ");
40
41     return 0;
42 }
43 static void hello_exit(void)
44 {
45     printk("hello_exit ");
46     return;
47 }
48
49 module_init(hello_init); //insmod
50 module_exit(hello_exit);//rmmod

Makefile

ifneq ($(KERNELRELEASE),)
obj-m:=hello.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD  :=$(shell pwd)
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ko *.o *.mod.o *.symvers *.cmd  *.mod.c *.order
endif

编译安装模块

dmesg -c
make
insmod hello.ko

【注意】都在root权限下操作

结果

可以看到在函数ccc中使用dump_stack()打印出了ccc的函数调用栈。

在内核开发中,我们可以使用dump_stack()来打印相关信息,同时在内核源码学习中也可以用来了解函数调用关系。


<上一页  1  2  
声明: 本文由入驻维科号的作者撰写,观点仅代表作者本人,不代表OFweek立场。如有侵权或其他问题,请联系举报。

发表评论

0条评论,0人参与

请输入评论内容...

请输入评论/评论长度6~500个字

您提交的评论过于频繁,请输入验证码继续

暂无评论

暂无评论

    人工智能 猎头职位 更多
    扫码关注公众号
    OFweek人工智能网
    获取更多精彩内容
    文章纠错
    x
    *文字标题:
    *纠错内容:
    联系邮箱:
    *验 证 码:

    粤公网安备 44030502002758号