core文件相關
1:當一個程序崩潰時,在進程當前工作目錄的core文件中復制了該進程的存儲圖像。core文件僅僅是一個內存映象(同時加上調試信息),主要是用來調試的。
當程序接收到以下UNIX信號會產生core文件:SIGABRT、SIGBUS、SIGEMT、SIGFPE、SIGILL、SIGIOT、SIGQUIT、SIGSEGV、SIGSYS、SIGTRAP、SIGXCPU、SIGXFSZ;
下面比較詳細地說明這些信號。
? SIGABRT 調用abort函數時產生此信號。進程異常終止。
? SIGBUS 指示一個實現定義的硬件故障。
? SIGEMT 指示一個實現定義的硬件故障。
? SIGFPE 此信號表示一個算術運算異常,例如除以0,浮點溢出等。
? SIGILL 此信號指示進程已執行一條非法硬件指令。
? SIGIOT 這指示一個實現定義的硬件故障。
? SIGQUIT 當用戶在終端上按退出鍵(一般采用Ctrl-\)時,產生此信號,並送至前臺進程組中的所有進程。此信號不僅終止前臺進程組(如SIGINT所做的那樣),同時產生一個core文件。
? SIGSEGV 指示進程進行了一次無效的存儲訪問。
? SIGSYS 指示一個無效的系統調用。由於某種未知原因,進程執行了一條系統調用指令,但其指示系統調用類型的參數卻是無效的。
? SIGTRAP 指示一個實現定義的硬件故障。
? SIGXCPU SVR4和4.3+BSD支持資源限制的概念。如果進程超過了其軟CPU時間限制,則產生此信號。
? SIGXFSZ 如果進程超過了其軟文件長度限制,則SVR4和4.3+BSD產生此信號。
摘自《UNIX環境高級編程》第10章 信號。
2:ulimint -a 用來顯示當前shell下的各種用戶進程限制
# ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7422 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 512000 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 7422 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
core file size 的值為0,說明當前環境不會產生core文件。
使用ulimit -c,可以設置core文件的大小,從而使得程序崩潰時可以產生core文件:
# ulimit -c 1024 # ulimit -a core file size (blocks, -c) 1024 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 7367 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 7367 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited
上面的命令,將core文件的大小最大設置為1024,單位為blocks,blocks的具體值與環境相關,可以通過查看/proc/<pid>/limits得到core文件的具體大小:
# cat /proc/self/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 10485760 unlimited bytes Max core file size 1048576 1048576 bytes Max resident set unlimited unlimited bytes Max processes 7367 7367 processes Max open files 1024 4096 files Max locked memory 65536 65536 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 7367 7367 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us
可見,core文件的最大為1048576字節,1048576/1024=1024,因此,blocks的值為1024。
可以通過ulimit -c unlimit命令,打開core文件的產生,並且不限制core文件的大小:
# ulimit -c unlimited # ulimit -a |grep core core file size (blocks, -c) unlimited # cat /proc/self/limits |grep core Max core file size unlimited unlimited bytes
可以通過ulimit -c 0關閉core文件的產生:
# ulimit -c 0 # ulimit -a|grep core core file size (blocks, -c) 0 # cat /proc/self/limits |grep core Max core file size 0 0 bytes
3:ulimit -c 命令進行的修改只是對當前shell有效,是臨時的。如果想讓修改永久生效,則需要修改配置文件,如 .bash_profile、/etc/profile或/etc/security/limits.conf。
比如,可以在/etc/profile文件的末尾加上一句:
ulimit -c unlimited
4:對於後臺服務而言,如果要生成core文件,還需要設置/proc/sys/kernel/core_pattern 文件的內容。該文件定義了core文件產生的路徑和文件名格式,比如:
echo "/data/cores/core_%e_%p_%t" > /proc/sys/kernel/core_pattern
上面的命令將core文件的路徑設置為"/data/cores",要註意該目錄必須存在,而且進程具有寫權限。文件名的格式設置為"core_%e_%p_%t",其中的格式化字符定義如下:
%% a single % character %c core file size soft resource limit of crashing process (since Linux 2.6.24) %d dump mode—same as value returned by prctl(2) PR_GET_DUMPABLE (since Linux 3.7) %e executable filename (without path prefix) %E pathname of executable, with slashes (‘/‘) replaced by exclamation marks (‘!‘) (since Linux 3.0). %g (numeric) real GID of dumped process %h hostname (same as nodename returned by uname(2)) %p PID of dumped process, as seen in the PID namespace in which the process resides %P PID of dumped process, as seen in the initial PID namespace (since Linux 3.12) %s number of signal causing dump %t time of dump, expressed as seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC) %u (numeric) real UID of dumped process
因此,上面設置的core文件名格式中包含了可執行程序名、程序ID,時間戳。註意,這裏的時間戳是1970之後的秒數,可以使用”date -d @XXX”命令,轉換為可讀時間:
# date -d @1504057088 Wed Aug 30 09:38:08 CST 2017
5:abrt
Redhat系列的系統中,其core_pattern的內容可能如下:
|/usr/libexec/abrt-hook-ccpp %s %c %p %u %g %t e
這是將產生的core文件傳遞給abrt-hook-ccpp程序,該程序是ABRT的一個組件。ABRT就是Automatic Bug Reporting Tool的縮寫。通過該工具,可以更全面的查看core文件的內容。具體參考:
https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/6/html/Deployment_Guide/ch-abrt.html
6:調試
用GDB調試core文件的命令:
gdb <filename> <core>
filename就是產生core文件的可執行文件,croe就是產生的core文件名。
使用 backtrace 或者 bt 打印當前的函數調用棧的所有信息。
如果要查看某一層的信息,你需要在切換當前的棧,一般來說,程序停止時,最頂層的棧就是當前棧,如果你要查看棧下面層的詳細信息,首先要做的是切換當前棧。
(gdb) f/frame <n> # n從0開始,是棧中的編號
(gdb) up <n> # 向棧的上面移動n層。如無n,向上移動一層
(gdb) down <n> # 向棧的下面移動n層。如無n,向下移動一層
# 這個命令會打印出更為詳細的當前棧層的信息,只不過,大多數都是運行時的內內地址。比如:函數地址,調用函數的地址,被調用函數的地址,目前的函數是由什麽樣的程序語言寫成的、函數參數地址及值、局部變量的地址等等。
(gdb) info f/frame
(gdb) info args # 打印當前函數的參數名及值
(gdb) info locals # 打印當前函數中所有局部變量及值
(gdb) info catch # 打印當前函數中的異常處理信息
基本上上面幾個命令就夠了,如果需要查看其他GDB調試命令,參考GDB手冊。
core文件相關