[Linux/C++] 在程式中加上版本字串,輔助 crash dump 分析
最近在查一些程式的 crash dump,
有一個很大的麻煩點就是…不知道這到底是哪一版程式產生的 crash dump…
當然如果是現場環境還保留著,自然可以從別的地方查到版本,
但有時可能只是送一個 dump file 過來叫你分析,
等你有空要去看的時候,環境不在了,
可能發現的人也不記得那時到底是用什麼版本的程式在跑… =_=
比較簡單的方式,就是在程式中加上版本字串,
這樣子如果程式當掉了,crash dump 裡面也可以查到版本的字串~
這方法在 Linux 上似乎是比較常用的。
下面是第一種實作嘗試:
#define VERSION_SZ "3.7" #define BUILD_SZ "1000" const char* TEST_MODULE_VER = "TestModule_" VERSION_SZ "." BUILD_SZ; int main() { return 0; }
要注意的是,這邊的 TEST_MODULE_VER 不能加上 static 修飾詞 (像是 static const char* TEST_MODULE_VER),
加上去的話,strings 就搜尋不到了!
編譯好的程式,用 strings 就可以搜尋到相關的版本字串:
將寫好的程式執行起來,再試著讓它當掉產生 crash dump,
接著用 strings 搜尋看看…
奇怪!如果這是一個 library 的話,居然找不到版本的字串!是怎麼一回事呢?
(非 library 的話,是可以找到的)
後來查到了 Linux Programmer’s Manual – core dump file 這邊的描述,
原來被 dump 出來的部分會根據 /proc/<PID>/coredump_filter 的內容來決定:
- bit 0 Dump anonymous private mappings.
- bit 1 Dump anonymous shared mappings.
- bit 2 Dump file-backed private mappings.
- bit 3 Dump file-backed shared mappings.
- bit 4 (since Linux 2.6.24) Dump ELF headers.
- bit 5 (since Linux 2.6.28) Dump private huge pages.
- bit 6 (since Linux 2.6.28) Dump shared huge pages.
所以像我的程式的 coredump_filter 內容是 3 的時候,
就只會 dump anonymous private/shared mappings (可參考 wikipedia 上的說明)~
假設版本字串是留在 file-backed mappings 上的話,core dump 就搜尋不到版本字串啦!
這邊可以有兩種解決方式:
第一種:讓 coredump 中也包含 file-backed mappings
把 bit 2/3 也都打開 (把值設為 15 = bit 0~3),
core dump 就可以搜尋到版本字串了,
只是缺點當然是 core dump 大小增加囉~~
第二種:讓版本字串直接出現在 anonymous mappings 中
如果版本字串直接是在 anonymous mappings 中的話,
coredump 中自然就會有版本字串了~
因此程式可以改成這樣:
#include <string.h> #define VERSION_SZ "3.7" #define BUILD_SZ "1000" char TEST_MODULE_VER[256] = ""; int main() { // Copy version string to global variable strcpy(TEST_MODULE_VER, "TestModule_" VERSION_SZ "." BUILD_SZ); return 0; }
這種寫法的話,就不管是編譯出來的程式本身,
或是 core dump file,都可以搜尋到版本字串囉~~^^
//
//