天天看點

關于Segmentation fault (core dumped)幾個簡單問題的整理 

  有的程式可以通過編譯,但在運作時會出現Segment fault(段錯誤)。這通常都是指針錯誤引起的。但這不像編譯錯誤一樣會提示到檔案一行,而是沒有任何資訊。一種辦法是用gdb的step, 一步一步尋找。但要step一個上萬行的代碼讓人難以想象。 我們還有更好的辦法,這就是core file。

如果想讓系統在信号中斷造成的錯誤時産生core檔案, 我們需要在shell中按如下設定:

#設定core大小為無限      ulimit -c unlimited

#設定檔案大小為無限       ulimit unlimited

發生core dump之後,用gdb進行檢視core檔案的内容, 以定位檔案中引發core dump的行:

gdb [exec file] [core file]

如: gdb ./test test.core 在進入gdb後, 用bt指令檢視backtrace以檢查發生程式運作到哪裡,來定位core dump的檔案->行。

另外需要注意的是,如果你的機器上跑很多的應用,你生成的core又不知道是哪個應用産生的,你可以通過下列指令進行檢視:file core

幾個問題:

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要注意這些問題:

一、要保證存放Coredump的目錄存在且程序對該目錄有寫權限。存放Coredump 的目錄即程序的目前目錄,一般就是當初發出指令啟動該程序時所在的目錄。但如果是通過腳本啟動,則腳本可能會修改目前目錄,這時程序真正的目前目錄就會與當初執行腳本所在目錄不同。這時可以檢視”/proc/程序pid>/cwd“符号連結的目标來确定程序真正的目前目錄位址。通過系統服務啟動的程序也可通過這一方法檢視。

二、若程式調用了seteuid()/setegid()改變了程序的有效使用者或組,則在預設情況下系統不會為這些程序生成Coredump。很多服務程式都會調用seteuid(),如MySQL,不論你用什麼使用者運作 mysqld_safe啟動MySQL,mysqld進行的有效使用者始終是msyql使用者。如果你當初是以使用者A運作了某個程式,但在ps裡看到的這個程式的使用者卻是B的話,那麼這些程序就是調用了seteuid了。為了能夠讓這些程序生成core dump,需要将/proc/sys/fs

/suid_dumpable 檔案的内容改為1(一般預設是0)。

三、這個一般都知道,就是要設定足夠大的Core檔案大小限制了。程式崩潰時生成的 Core檔案大小即為程式運作時占用的記憶體大小。但程式崩潰時的行為不可按平常時的行為來估計,比如緩沖區溢出等錯誤可能導緻堆棧被破壞,是以經常會出現某個變量的值被修改成亂七八糟的,然後程式用這個大小去申請記憶體就可能導緻程式比平常時多占用很多記憶體。是以無論程式正常運作時占用的記憶體多麼少,要保證生成Core檔案還是将大小限制設為unlimited為好。

四、異常退出就一定會生成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   終止程序   虛拟計時器到

把可能的信号都設定上句柄,看是那種情況。

原文連結:http://www.daifuxin.com/post%20cat_5%20user_4%202012%2002%2019%2027%2027%20/

轉載于:https://www.cnblogs.com/followyourdream/p/3289367.html