溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Segmentation fault的簡單問題有哪些

發(fā)布時間:2021-12-30 16:28:28 來源:億速云 閱讀:188 作者:柒染 欄目:云計算

本篇文章為大家展示了Segmentation fault的簡單問題有哪些,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

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

如果想讓系統(tǒng)在信號中斷造成的錯誤時產生core文件, 我們需要在shell中按如下設置:

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

#設置文件大小為無限       ulimit unlimited

發(fā)生core dump之后,用gdb進行查看core文件的內容, 以定位文件中引發(fā)core dump的行:

gdb [exec file] [core file]

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

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

 幾個問題:

1. 什么是Core:

在使用半導體作為內存的材料前,人類是利用線圈當作內存的材料(發(fā)明者為王安),線圈就叫作 core ,用線圈做的內存就叫作 core memory。如今 ,半導體工業(yè)澎勃發(fā)展,已經沒有人用 core memory 了,不過,在許多情況下,人們還是把記憶體叫作 core 。

2. 什么是Core Dump:

我們在開發(fā)(或使用)一個程序時,最怕的就是程序莫明其妙地當?shù)簟km然系統(tǒng)沒事,但我們下次仍可能遇到相同的問題。于是這時操作系統(tǒng)就會把程序當?shù)?時的內存內容 dump 出來(現(xiàn)在通常是寫在一個叫 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的核心轉儲文件目錄和命名規(guī)則:

/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的目錄即進程的當前目錄,一般就是當初發(fā)出命令啟動該進程時所在的目錄。但如果是通過腳本啟動,則腳本可能會修改當前目錄,這時進程真正的當前目錄就會與當初執(zhí)行腳本所在目錄不同。這時可以查看”/proc/<進程pid>/cwd“符號鏈接的目標來確定進程真正的當前目錄地址。通過系統(tǒng)服務啟動的進程也可通過這一方法查看。

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

可通過以下命令修改此文件:

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

可以將core文件統(tǒng)一生成到/corefile目錄下,產生的文件名為core-命令名-pid-時間戳

以下是參數(shù)列表:

 %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 的目錄即進程的當前目錄,一般就是當初發(fā)出命令啟動該進程時所在的目錄。但如果是通過腳本啟動,則腳本可能會修改當前目錄,這時進程真正的當前目錄就會與當初執(zhí)行腳本所在目錄不同。這時可以查看”/proc/進程pid>/cwd“符號鏈接的目標來確定進程真正的當前目錄地址。通過系統(tǒng)服務啟動的進程也可通過這一方法查看。

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

/suid_dumpable 文件的內容改為1(一般默認是0)。

三、這個一般都知道,就是要設置足夠大的Core文件大小限制了。程序崩潰時生成的 Core文件大小即為程序運行時占用的內存大小。但程序崩潰時的行為不可按平常時的行為來估計,比如緩沖區(qū)溢出等錯誤可能導致堆棧被破壞,因此經常會出現(xiàn)某個變量的值被修改成亂七八糟的,然后程序用這個大小去申請內存就可能導致程序比平常時多占用很多內存。因此無論程序正常運行時占用的內存多么少,要保證生成Core文件還是將大小限制設為unlimited為好。

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

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

SIGHUP   終止進程   終端線路掛斷

SIGINT   終止進程   中斷進程

SIGQUIT   建立CORE文件終止進程,并且生成core文件

SIGILL   建立CORE文件   非法指令

SIGTRAP   建立CORE文件   跟蹤自陷

SIGBUS   建立CORE文件   總線錯誤

SIGSEGV   建立CORE文件   段非法錯誤

SIGFPE   建立CORE文件   浮點異常

SIGIOT   建立CORE文件   執(zhí)行I/O自陷

SIGKILL   終止進程   殺死進程

SIGPIPE   終止進程   向一個沒有讀進程的管道寫數(shù)據(jù)

SIGALARM   終止進程   計時器到時

SIGTERM   終止進程   軟件終止信號

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

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

SIGCONT   忽略信號   繼續(xù)執(zhí)行一個停止的進程

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

SIGIO   忽略信號   描述符上可以進行I/O

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

SIGTTOU   停止進程   后臺進程寫終端

SIGTTIN   停止進程   后臺進程讀終端

SIGXGPU   終止進程   CPU時限超時

SIGXFSZ   終止進程   文件長度過長

SIGWINCH   忽略信號   窗口大小發(fā)生變化

SIGPROF   終止進程   統(tǒng)計分布圖用計時器到時

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

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

SIGVTALRM   終止進程   虛擬計時器到

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

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

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

一般情況下,linux系統(tǒng)是不允許產生core文件的,因此首先要解除這個限制:

ulimit -c unlimited

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

./test

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

Segmentation fault (core dumped)

在該文件夾下會出現(xiàn)一個名為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 ()

上述內容就是Segmentation fault的簡單問題有哪些,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業(yè)資訊頻道。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經查實,將立刻刪除涉嫌侵權內容。

AI