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
在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