關於Segmentation fault (core dumped)幾個簡單問題

有的程序能夠經過編譯,但在運行時會出現Segment fault(段錯誤)。這一般都是指針錯誤引發的。但這不像編譯錯誤同樣會提示到文件一行,而是沒有任何信息。一種辦法是用gdb的step, 一步一步尋找。但要step一個上萬行的代碼讓人不可思議。 咱們還有更好的辦法,這就是core file。mysql

若是想讓系統在信號中斷形成的錯誤時產生core文件, 咱們須要在shell中按以下設置:linux

#設置core大小爲無限      ulimit -c unlimitedsql

#設置文件大小爲無限       ulimit unlimitedshell

發生core dump以後,用gdb進行查看core文件的內容, 以定位文件中引起core dump的行:bash

gdb [exec file] [core file]app

如: gdb ./test test.core 在進入gdb後, 用bt命令查看backtrace以檢查發生程序運行到哪裏,來定位core dump的文件->行。ide

另外須要注意的是,若是你的機器上跑不少的應用,你生成的core又不知道是哪一個應用產生的,你能夠經過下列命令進行查看:file coreui

 

 幾個問題:spa

1. 什麼是Core:操作系統

在使用半導體做爲內存的材料前,人類是利用線圈看成內存的材料(發明者爲王安),線圈就叫做 core ,用線圈作的內存就叫做 core memory。現在 ,半導體工業澎勃發展,已經沒有人用 core memory 了,不過,在許多狀況下,人們仍是把記憶體叫做 core 。

2. 什麼是Core Dump:

咱們在開發(或使用)一個程序時,最怕的就是程序莫明其妙地當掉。雖然系統沒事,但咱們下次仍可能遇到相同的問題。因而這時操做系統就會把程序當掉 時的內存內容 dump 出來(如今一般是寫在一個叫 core 的 file 裏面),讓 咱們或是 debugger 作爲參考。這個動做就叫做 core dump。

 3. Core Dump時會生成何種文件:

Core Dump時,會生成諸如 core.進程號 的文件。

 4. 爲什麼有時程序Down了,卻沒生成 Core文件。

Linux下,有一些設置,標明瞭resources available to the shell and to processes。 可使用

#ulimit -a 來看這些設置。 (ulimit是bash built-in Command)

從這裏能夠看出,若是 -c是顯示:core file size。若是這個值爲0,則沒法生成core文件。因此可使用:#ulimit -c 1024   或者 #ulimit -c unlimited   來使能 core文件。若是程序出錯時生成Core 文件,則會顯示Segmentation fault (core dumped) 。

 5. Core Dump的核心轉儲文件目錄和命名規則:

/proc/sys/kernel /core_uses_pid能夠控制產生的core文件的文件名中是否添加pid做爲擴展,若是添加則文件內容爲1,不然爲0

可經過如下命令修改此文件:

echo   "1" > /proc/sys/kernel/core_uses_pid

 6. 如何使用Core文件:

在linux下,使用:

#gdb -c core.pid program_name

就能夠進入gdb模式。

輸入where,就能夠指出是在哪一行被Down掉,哪一個function內,由誰調用等等。

(gdb) where

或者輸入 bt。

(gdb) bt

7. 如何讓一個正常的程序down:

#kill -s SIGSEGV pid

8. 察看Core文件輸出在何處:

存放Coredump的目錄即進程的當前目錄,通常就是當初發出命令啓動該進程時所在的目錄。但若是是經過腳本啓動,則腳本可能會修改當前目錄,這時進程真正的當前目錄就會與當初執行腳本所在目錄不一樣。這時能夠查看」/proc/<進程pid>/cwd「符號連接的目標來肯定進程真正的當前目錄地址。經過系統服務啓動的進程也可經過這一方法查看。

proc/sys/kernel /core_pattern能夠控制core文件保存位置和文件名格式。

可經過如下命令修改此文件:

echo  "/corefile/core-%e-%p-%t" >core_pattern

能夠將core文件統一輩子成到/corefile目錄下,產生的文件名爲core-命令名-pid-時間戳

如下是參數列表:

 %p - insert pid into filename 添加pid

%u - insert current uid into filename 添加當前uid

%g - insert current gid into filename 添加當前gid

%s - insert signal that caused the coredump into the filename 添加致使產生core的信號

%t - insert UNIX time that the coredump occurred into filename 添加core文件生成時的unix時間

 %h - insert hostname where the coredump happened into filename 添加主機名

%e - insert coredumping executable name into filename 添加命令名

 

 在Linux下要保證程序崩潰時生成 Coredump要注意這些問題:

1、要保證存放Coredump的目錄存在且進程對該目錄有寫權限。存放Coredump 的目錄即進程的當前目錄,通常就是當初發出命令啓動該進程時所在的目錄。但若是是經過腳本啓動,則腳本可能會修改當前目錄,這時進程真正的當前目錄就會與當初執行腳本所在目錄不一樣。這時能夠查看」/proc/進程pid>/cwd「符號連接的目標來肯定進程真正的當前目錄地址。經過系統服務啓動的進程也可經過這一方法查看。

2、若程序調用了seteuid()/setegid()改變了進程的有效用戶或組,則在默認狀況下系統不會爲這些進程生成Coredump。不少服務程序都會調用seteuid(),如MySQL,不論你用什麼用戶運行 mysqld_safe啓動mysql,mysqld進行的有效用戶始終是msyql用戶。若是你當初是以用戶A運行了某個程序,但在ps裏看到的這個程序的用戶倒是B的話,那麼這些進程就是調用了seteuid了。爲了可以讓這些進程生成core dump,須要將/proc/sys/fs

/suid_dumpable 文件的內容改成1(通常默認是0)。

3、這個通常都知道,就是要設置足夠大的Core文件大小限制了。程序崩潰時生成的 Core文件大小即爲程序運行時佔用的內存大小。但程序崩潰時的行爲不可按日常時的行爲來估計,好比緩衝區溢出等錯誤可能致使堆棧被破壞,所以常常會出現某個變量的值被修改爲亂七八糟的,而後程序用這個大小去申請內存就可能致使程序比日常時多佔用不少內存。所以不管程序正常運行時佔用的內存多麼少,要保證生成Core文件仍是將大小限制設爲unlimited爲好。

4、異常退出就必定會生成core嗎? 難道沒有不生成core的異常退出?

若是不是正常退出的那就是有信號引發的程序退出,有些信號確實能引發程序退出但不生成core。

SIGHUP   終止進程   終端線路掛斷

SIGINT   終止進程   中斷進程

SIGQUIT   創建CORE文件終止進程,而且生成core文件

SIGILL   創建CORE文件   非法指令

SIGTRAP   創建CORE文件   跟蹤自陷

SIGBUS   創建CORE文件   總線錯誤

SIGSEGV   創建CORE文件   段非法錯誤

SIGFPE   創建CORE文件   浮點異常

SIGIOT   創建CORE文件   執行I/O自陷

SIGKILL   終止進程   殺死進程

SIGPIPE   終止進程   向一個沒有讀進程的管道寫數據

SIGALARM   終止進程   計時器到時

SIGTERM   終止進程   軟件終止信號

SIGSTOP   中止進程   非終端來的中止信號

SIGTSTP   中止進程   終端來的中止信號

SIGCONT   忽略信號   繼續執行一箇中止的進程

SIGURG   忽略信號   I/O緊急信號

SIGIO   忽略信號   描述符上能夠進行I/O

SIGCHLD   忽略信號   當子進程中止或退出時通知父進程

SIGTTOU   中止進程   後臺進程寫終端

SIGTTIN   中止進程   後臺進程讀終端

SIGXGPU   終止進程   CPU時限超時

SIGXFSZ   終止進程   文件長度過長

SIGWINCH   忽略信號   窗口大小發生變化

SIGPROF   終止進程   統計分佈圖用計時器到時

SIGUSR1   終止進程   用戶定義信號1

SIGUSR2   終止進程   用戶定義信號2

SIGVTALRM   終止進程   虛擬計時器到

把可能的信號都設置上句柄,看是那種狀況。


Segmentation fault(段錯誤)是因爲虛擬內存管理單元的異常所致,而該異常則一般是因爲解引用一個未初始化或非法值的指針引發的。

Linux中提供了core dump的功能,使得對這類錯誤的調試更爲容易。


通常狀況下,linux系統是不容許產生core文件的,所以首先要解除這個限制:

ulimit -c unlimited

接下來,運行含segmentation fault的段程序,如:

./test

這時,segmentation fault的錯誤信息會顯示爲:

Segmentation fault (core dumped)

在該文件夾下會出現一個名爲core的文件

使用生成的core文件進行調試

gdb test core

(gdb) bt

#0  0x00a5c920 in ?? () from /lib/i386-linux-gnu/libc.so.6#1  0x00a5ca0d in exit () from /lib/i386-linux-gnu/libc.so.6#2  0x00a4311b in __libc_start_main () from /lib/i386-linux-gnu/libc.so.6#3  0x080483d1 in _start ()

相關文章
相關標籤/搜索