Segmentationfault的簡(jiǎn)單問(wèn)題有哪些

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

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開(kāi)發(fā)、重慶小程序開(kāi)發(fā)公司、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了南陽(yáng)免費(fèi)建站歡迎大家使用!

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

如果想讓系統(tǒng)在信號(hào)中斷造成的錯(cuò)誤時(shí)產(chǎn)生core文件, 我們需要在shell中按如下設(shè)置:

#設(shè)置core大小為無(wú)限      ulimit -c unlimited

#設(shè)置文件大小為無(wú)限       ulimit unlimited

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

gdb [exec file] [core file]

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

另外需要注意的是,如果你的機(jī)器上跑很多的應(yīng)用,你生成的core又不知道是哪個(gè)應(yīng)用產(chǎn)生的,你可以通過(guò)下列命令進(jìn)行查看:file core

 幾個(gè)問(wèn)題:

1. 什么是Core:

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

2. 什么是Core Dump:

我們?cè)陂_(kāi)發(fā)(或使用)一個(gè)程序時(shí),最怕的就是程序莫明其妙地當(dāng)?shù)?。雖然系統(tǒng)沒(méi)事,但我們下次仍可能遇到相同的問(wèn)題。于是這時(shí)操作系統(tǒng)就會(huì)把程序當(dāng)?shù)?時(shí)的內(nèi)存內(nèi)容 dump 出來(lái)(現(xiàn)在通常是寫(xiě)在一個(gè)叫 core 的 file 里面),讓 我們或是 debugger 做為參考。這個(gè)動(dòng)作就叫作 core dump。

 3. Core Dump時(shí)會(huì)生成何種文件:

Core Dump時(shí),會(huì)生成諸如 core.進(jìn)程號(hào) 的文件。

 4. 為何有時(shí)程序Down了,卻沒(méi)生成 Core文件。

Linux下,有一些設(shè)置,標(biāo)明了resources available to the shell and to processes。 可以使用

#ulimit -a 來(lái)看這些設(shè)置。 (ulimit是bash built-in Command)

從這里可以看出,如果 -c是顯示:core file size。如果這個(gè)值為0,則無(wú)法生成core文件。所以可以使用:#ulimit -c 1024   或者 #ulimit -c unlimited   來(lái)使能 core文件。如果程序出錯(cuò)時(shí)生成Core 文件,則會(huì)顯示Segmentation fault (core dumped) 。

 5. Core Dump的核心轉(zhuǎn)儲(chǔ)文件目錄和命名規(guī)則:

/proc/sys/kernel /core_uses_pid可以控制產(chǎn)生的core文件的文件名中是否添加pid作為擴(kuò)展,如果添加則文件內(nèi)容為1,否則為0

可通過(guò)以下命令修改此文件:

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

 6. 如何使用Core文件:

在linux下,使用:

#gdb -c core.pid program_name

就可以進(jìn)入gdb模式。

輸入where,就可以指出是在哪一行被Down掉,哪個(gè)function內(nèi),由誰(shuí)調(diào)用等等。

(gdb) where

或者輸入 bt。

(gdb) bt

7. 如何讓一個(gè)正常的程序down:

#kill -s SIGSEGV pid

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

存放Coredump的目錄即進(jìn)程的當(dāng)前目錄,一般就是當(dāng)初發(fā)出命令啟動(dòng)該進(jìn)程時(shí)所在的目錄。但如果是通過(guò)腳本啟動(dòng),則腳本可能會(huì)修改當(dāng)前目錄,這時(shí)進(jìn)程真正的當(dāng)前目錄就會(huì)與當(dāng)初執(zhí)行腳本所在目錄不同。這時(shí)可以查看”/proc/<進(jìn)程pid>/cwd“符號(hào)鏈接的目標(biāo)來(lái)確定進(jìn)程真正的當(dāng)前目錄地址。通過(guò)系統(tǒng)服務(wù)啟動(dòng)的進(jìn)程也可通過(guò)這一方法查看。

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

可通過(guò)以下命令修改此文件:

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

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

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

 %p - insert pid into filename 添加pid

%u - insert current uid into filename 添加當(dāng)前uid

%g - insert current gid into filename 添加當(dāng)前gid

%s - insert signal that caused the coredump into the filename 添加導(dǎo)致產(chǎn)生core的信號(hào)

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

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

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

 在Linux下要保證程序崩潰時(shí)生成 Coredump要注意這些問(wèn)題:

一、要保證存放Coredump的目錄存在且進(jìn)程對(duì)該目錄有寫(xiě)權(quán)限。存放Coredump 的目錄即進(jìn)程的當(dāng)前目錄,一般就是當(dāng)初發(fā)出命令啟動(dòng)該進(jìn)程時(shí)所在的目錄。但如果是通過(guò)腳本啟動(dòng),則腳本可能會(huì)修改當(dāng)前目錄,這時(shí)進(jìn)程真正的當(dāng)前目錄就會(huì)與當(dāng)初執(zhí)行腳本所在目錄不同。這時(shí)可以查看”/proc/進(jìn)程pid>/cwd“符號(hào)鏈接的目標(biāo)來(lái)確定進(jìn)程真正的當(dāng)前目錄地址。通過(guò)系統(tǒng)服務(wù)啟動(dòng)的進(jìn)程也可通過(guò)這一方法查看。

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

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

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

四、異常退出就一定會(huì)生成core嗎? 難道沒(méi)有不生成core的異常退出?

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

SIGHUP   終止進(jìn)程   終端線路掛斷

SIGINT   終止進(jìn)程   中斷進(jìn)程

SIGQUIT   建立CORE文件終止進(jìn)程,并且生成core文件

SIGILL   建立CORE文件   非法指令

SIGTRAP   建立CORE文件   跟蹤自陷

SIGBUS   建立CORE文件   總線錯(cuò)誤

SIGSEGV   建立CORE文件   段非法錯(cuò)誤

SIGFPE   建立CORE文件   浮點(diǎn)異常

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

SIGKILL   終止進(jìn)程   殺死進(jìn)程

SIGPIPE   終止進(jìn)程   向一個(gè)沒(méi)有讀進(jìn)程的管道寫(xiě)數(shù)據(jù)

SIGALARM   終止進(jìn)程   計(jì)時(shí)器到時(shí)

SIGTERM   終止進(jìn)程   軟件終止信號(hào)

SIGSTOP   停止進(jìn)程   非終端來(lái)的停止信號(hào)

SIGTSTP   停止進(jìn)程   終端來(lái)的停止信號(hào)

SIGCONT   忽略信號(hào)   繼續(xù)執(zhí)行一個(gè)停止的進(jìn)程

SIGURG   忽略信號(hào)   I/O緊急信號(hào)

SIGIO   忽略信號(hào)   描述符上可以進(jìn)行I/O

SIGCHLD   忽略信號(hào)   當(dāng)子進(jìn)程停止或退出時(shí)通知父進(jìn)程

SIGTTOU   停止進(jìn)程   后臺(tái)進(jìn)程寫(xiě)終端

SIGTTIN   停止進(jìn)程   后臺(tái)進(jìn)程讀終端

SIGXGPU   終止進(jìn)程   CPU時(shí)限超時(shí)

SIGXFSZ   終止進(jìn)程   文件長(zhǎng)度過(guò)長(zhǎng)

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

SIGPROF   終止進(jìn)程   統(tǒng)計(jì)分布圖用計(jì)時(shí)器到時(shí)

SIGUSR1   終止進(jìn)程   用戶定義信號(hào)1

SIGUSR2   終止進(jìn)程   用戶定義信號(hào)2

SIGVTALRM   終止進(jìn)程   虛擬計(jì)時(shí)器到

把可能的信號(hào)都設(shè)置上句柄,看是那種情況。

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

Linux中提供了core dump的功能,使得對(duì)這類錯(cuò)誤的調(diào)試更為容易。

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

ulimit -c unlimited

接下來(lái),運(yùn)行含segmentation fault的段程序,如:

./test

這時(shí),segmentation fault的錯(cuò)誤信息會(huì)顯示為:

Segmentation fault (core dumped)

在該文件夾下會(huì)出現(xiàn)一個(gè)名為core的文件

使用生成的core文件進(jìn)行調(diào)試

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 ()

上述內(nèi)容就是Segmentation fault的簡(jiǎn)單問(wèn)題有哪些,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

名稱欄目:Segmentationfault的簡(jiǎn)單問(wèn)題有哪些
分享鏈接:http://muchs.cn/article38/jcjgsp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營(yíng)銷靜態(tài)網(wǎng)站、域名注冊(cè)、外貿(mào)網(wǎng)站建設(shè)、商城網(wǎng)站、網(wǎng)頁(yè)設(shè)計(jì)公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

商城網(wǎng)站建設(shè)