自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Linux下查看函數(shù)被那些函數(shù)調(diào)用過?

系統(tǒng) Linux
有個打印log的函數(shù),想知道該函數(shù)執(zhí)行的時候,之前執(zhí)行了哪些函數(shù)?

[[389563]]

 一、問題

有個打印log的函數(shù),想知道該函數(shù)執(zhí)行的時候,之前執(zhí)行了哪些函數(shù)?


二、分析

在應(yīng)用程序打印函數(shù)棧需要通過函數(shù)backtrace(),該函數(shù)對應(yīng)頭文件如下:

  1. #include <execinfo.h> 

1、三個與打印調(diào)用棧相關(guān)的函數(shù)

打印函數(shù)棧需要使用到以下3個函數(shù)

  1. int backtrace(void** buffer, int size); 

函數(shù)功能:用于獲取當(dāng)前線程的調(diào)用堆棧。參數(shù):buffer:它是一個指針數(shù)組,函數(shù)獲取的當(dāng)前線程的調(diào)用堆棧將會被存放在buffer中。在buffer中的指針實際是從堆棧中獲取的返回地址,每一個堆棧 框架有一個返回地址。size:用來指定buffer中可以保存多少個void*元素。返回值:實際獲取的指針個數(shù),最大不超過size大小。

char** backtrace_symbols (void *const *buffer, int size);

函數(shù)功能:將從backtrace函數(shù)獲取的信息轉(zhuǎn)化為一個字符串?dāng)?shù)組。參數(shù):buffer:從backtrace函數(shù)獲取的數(shù)組指針。size:是該數(shù)組中的元素個數(shù)(backtrace函數(shù)的返回值)。返回值:是一個指向字符串?dāng)?shù)組的指針,它的大小同buffer相同。每個字符串包含了一個相對于buffer中對應(yīng)元素的 可打印信息。它包括函數(shù)名,函數(shù)的偏移地址,和實際的返回地址。

注:

  • 1、只有使用ELF二進制格式的程序才能獲取函數(shù)名稱和偏移地址。在其他系統(tǒng),只有16進制的返回地址能被獲取。另外,需要傳遞相應(yīng)的標(biāo)志給鏈接器,以能支持函數(shù)名功能即編譯選項-rdynamic。
  • 2、backtrace_symbols生成的字符串都是malloc出來的,最后需要free該塊內(nèi)存。
  1. void backtrace_symbols_fd (void *const *buffer, int sizeint fd) 

功能:backtrace_symbols_fd與backtrace_symbols函數(shù)具有相同的功能,不同的是它不會給調(diào)用者返回字符串?dāng)?shù)組,而是將結(jié)果寫入文件描述符為fd的文件中,每個函數(shù)對應(yīng)一行.它不需要調(diào)用malloc函數(shù),因此適用于有可能調(diào)用該函數(shù)會失敗的情況。參數(shù):fd:通常填寫STDOUT_FILENO

2. 鏈接庫

在編譯的時候需要加上**-rdynamic**選項。

  1. -rdynamic 
  2.      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. 

該選項讓鏈接器將所有符號添加到動態(tài)符號表中,這樣才能將函數(shù)地址翻譯成函數(shù)名,否則打印的結(jié)果是不會打印函數(shù)名的。

另外,這個選項不會處理static函數(shù),所以,static函數(shù)的符號無法得到。

3. 舉例

  1. #include <execinfo.h> 
  2. #include <stdio.h> 
  3. #include <stdlib.h> 
  4. #include <unistd.h> 
  5.   
  6. void fun1(); 
  7. void fun2(); 
  8. void fun3(); 
  9.   
  10. void print_stacktrace(); 
  11.   
  12. void print_stacktrace() 
  13.     int size = 16; 
  14.     void * array[100]; 
  15.   
  16.     int stack_num = backtrace(array, size); 
  17.   
  18.  char ** stacktrace = backtrace_symbols(array, stack_num); 
  19.   
  20.  backtrace_symbols_fd(array,size,STDOUT_FILENO); 
  21.   
  22. #if 0 
  23.     char ** stacktrace = backtrace_symbols(array, stack_num); 
  24.   
  25.     for (int i = 0; i < stack_num; ++i) 
  26.     { 
  27.         printf("%s\n", stacktrace[i]); 
  28.     } 
  29.     free(stacktrace); 
  30. #endif 
  31. void fun1() 
  32.     printf("stackstrace begin:\n"); 
  33.     print_stacktrace(); 
  34. void fun2() 
  35.     fun1(); 
  36. void fun3() 
  37.     fun2(); 
  38. int main() 
  39.     fun3(); 
  40.   

編譯運行g(shù)cc編譯時加上-rdynamic參數(shù),通知鏈接器支持函數(shù)名功能(不加-rdynamic參數(shù)則無函數(shù)名打印):

  1. gcc 123.c -o run -rdynamic -g 

執(zhí)行結(jié)果:


4. 補充 address2line

同一個函數(shù)可以在代碼中多個地方調(diào)用,如果我們只是知道函數(shù),要想知道在哪里調(diào)用了該函數(shù),可以通過address2line命令來完成,我們用第2步中編譯出來的test2來做實驗(address2line的-f選項可以打出函數(shù)名, -C選項也可以demangle):

address2line

三、內(nèi)核代碼中如何打印函數(shù)棧?

在Linux內(nèi)核中提供了一個可以打印出內(nèi)核調(diào)用堆棧的函數(shù) dump_stack()。

該函數(shù)在我們調(diào)試內(nèi)核的過程中可以打印出函數(shù)調(diào)用關(guān)系,該函數(shù)可以幫助我們進行內(nèi)核調(diào)試,以及讓我們了解內(nèi)核的調(diào)用關(guān)系。

1. 頭文件

該函數(shù)頭文件為:

  1. #include <asm/ptrace.h> 

使用方式:

直接在想要查看的函數(shù)中添加

  1. dump_stack(); 

2. 舉例

測試代碼如下:hello.c

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

Makefile

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

編譯安裝模塊

  1. dmesg -c 
  2. make 
  3. insmod hello.ko 

【注意】 都在root權(quán)限下操作

結(jié)果

可以看到在函數(shù)ccc中使用dump_stack()打印出了ccc的函數(shù)調(diào)用棧。

在內(nèi)核開發(fā)中,我們可以使用dump_stack()來打印相關(guān)信息,同時在內(nèi)核源碼學(xué)習(xí)中也可以用來了解函數(shù)調(diào)用關(guān)系。

 

責(zé)任編輯:姜華 來源: 一口Linux
相關(guān)推薦

2011-04-25 16:35:06

Linux調(diào)用

2010-01-12 11:48:59

Linuxitoa函數(shù)

2009-08-05 09:40:02

C#調(diào)用DLL函數(shù)

2020-09-28 08:12:59

CC++時間

2020-01-17 20:00:25

SQL函數(shù)數(shù)據(jù)庫

2023-10-26 11:37:35

函數(shù)Python

2023-10-26 11:39:54

Linux系統(tǒng)CPU

2017-03-08 15:39:11

Linuxselect函數(shù)

2022-05-18 08:00:26

函數(shù)劫持JavaScript鉤子函數(shù)

2024-01-15 09:15:52

parallel語句函數(shù)

2021-11-30 08:44:29

SpringRouter Func函數(shù)式接口

2010-07-28 15:29:18

Flex函數(shù)

2010-01-28 13:35:41

調(diào)用C++函數(shù)

2010-05-31 09:19:53

PHP

2010-06-18 10:42:51

Linux Acces

2023-12-22 16:39:47

Java函數(shù)式接口開發(fā)

2020-08-16 10:58:20

Pandaspython開發(fā)

2023-09-09 12:23:24

函數(shù)式接口程序

2009-10-21 13:02:20

linux串口操作函數(shù)操作系統(tǒng)

2017-03-16 14:37:05

LinuxShell函數(shù)
點贊
收藏

51CTO技術(shù)棧公眾號