Linux 下打印程序調用棧callstack


Linux下打印程序調用棧callstack

1. Java代碼中打印堆棧

Java代碼打印堆棧比較簡單, 堆棧信息獲取和輸出,都可以通過Throwable類的方法實現。目前通用的做法是在java進程出現需要注意的異常時,打印堆棧,然后再決定退出或挽救。通常的方法是使用exception的printStackTrace()方法:

1 try {
2 ...
3 } catch (RemoteException e) {
4 
5 e.printStackTrace();
6 ...
7 }

當然也可以只打印堆棧不退出,這樣就比較方便分析代碼的動態運行情況。Java代碼中插入堆棧打印的方法如下:

1 Log.d(TAG,Log.getStackTraceString(new Throwable()));

 

2. C++代碼中打印堆棧

2.1 通過捕獲異常

參考文章:

https://stackoverflow.com/questions/3899870/print-call-stack-in-c-or-c/26529030

https://blog.csdn.net/Zhanglin_Wu/article/details/109333908?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2~aggregatepage~first_rank_ecpm_v1~rank_aggregation-3-109333908.pc_agg_rank_aggregation&utm_term=call+stack%E5%9C%A8c%2B%2B%E4%B8%AD&spm=1000.2123.3001.4430

在Linux中運行的C++程序,如果拋出的異常(exception)未被捕獲,則可以用一些方法強行打印出調用棧(callstack),以下僅為示例:

 1 #include <exception>
 2 #include <iostream>
 3 #include <string>
 4 
 5 #include <execinfo.h>
 6 #include <unistd.h>
 7 
 8 using namespace std;
 9 
10 void print_trace(void) {
11     size_t i, size;
12     enum Constexpr { MAX_SIZE = 1024 };
13     void *array[MAX_SIZE];
14     
15     size = backtrace(array, MAX_SIZE);
16     backtrace_symbols_fd(array, size, STDOUT_FILENO);
17     
18     puts("");
19 }
20 
21 int main(int argc, char* argv[])
22 {
23     std::set_terminate([](){
24         cout << "Unhandled exception with callstack:" << std::endl;
25         print_trace();
26         std::abort();
27     });
28 
29     throw runtime_error("This is an exception");
30 
31     return 0;
32 }

 

2.2 直接打印堆棧

C++也是支持異常處理的,異常處理庫中,已經包含了獲取backtrace的接口,Android也是利用這個接口來打印堆棧信息的。在Android的C++中,已經集成了一個工具類CallStack,在libutils.so中。使用方法:

1 #include <utils/CallStack.h>
2 
3 ...
4 CallStack stack;
5 stack.update();
6 stack.dump();

使用方式比較簡單。目前Andoid4.2版本已經將相關信息解析的很到位,符號表查找,demangle,偏移位置校正都做好了。

3. C代碼中打印堆棧

下面代碼只能用在 usespace,kernel space需要重新去封裝:

 1 #include <execinfo.h>
 2 
 3 void kmj_print_trace (void)
 4 {
 5     void *array[16];
 6     size_t size;
 7     char **strings;
 8     size_t i;
 9 
10     size = backtrace (array, 16);
11     strings = (char **)backtrace_symbols (array, size);
12     printf("[dump_stack]print_trace[pid=%d]\n", getpid());
13 
14     for (i = 0; i < size; i++)
15     {
16         printf("%s\n", strings[i]);
17     }
18     free (strings);
19 }

 

kernel space:

在Linux內核調試中,經常用到的打印函數調用堆棧的方法非常簡單,只需在需要查看堆棧的函數中加入:

dump_stack();或 __backtrace();即可。

dump_stack() 在 ~/kernel/lib/Dump_stack.c中定義:

1 void dump_stack(void)
2 {
3      printk(KERN_NOTICE  "This architecture does not implement dump_stack()/n");
4 }

__backtrace() 的定義在~/kernel/arch/arm/lib/backtrace.S中

1 ENTRY(__backtrace)
2   mov r1, #0x10
3   mov r0, fp

 

參考文章:

https://www.cnblogs.com/catgatp/p/6363505.html

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM