1. 程式人生 > >core文件相關

core文件相關

組件 catch sta porting har auto 進行 指示 gre

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文件相關