五月丁香综合缴情六月|日韩精品无码专区一区|亚洲熟女乱综合一区二区|中文字幕无码一日不在线|国产欧美视频一区二区三区|国产精品日韩欧美在线播放|亚洲第一极品精品无码不卡|99ri在线精品视频在线播放

下載手機(jī)汽配人

centos中出現(xiàn)sigsegv和sigbus錯(cuò)誤,怎么辦

提問者:網(wǎng)友 2017-12-20
最佳回答
SIGBUS和SIGSEGV也許是我們在平時(shí)遇到的次數(shù)最多的兩個(gè)內(nèi)存錯(cuò)誤信號。內(nèi)存問題一直是最令我們頭疼的事情,弄清楚兩個(gè)信號的發(fā)生緣由對我們很好的理解程序的運(yùn)行是大有裨益的。我們來看兩段程序://testsigsegv.cint main() { char *pc = (char*)0x00001111; *pc = 17;}//testsigbus.cint main() { int *pi = (int*)0x00001111; *pi = 17;}上面的代碼那么的相似,我們也同樣用gcc編譯(加上-g選項(xiàng),便于gdb調(diào)試;平臺Solaris Sparc),執(zhí)行結(jié)果也都是dump core。但通過GDB對core進(jìn)行觀察,你會發(fā)現(xiàn)細(xì)微的不同。第一個(gè)例子出的core原因是:Program terminated with signal 11, Segmentation fault. 而第二個(gè)例子的core則提示:Program terminated with signal 10, Bus error. 兩者有什么不同呢?這兩段代碼的共同點(diǎn)都是將一個(gè)非法地址賦值給指針變量,然后試圖寫數(shù)據(jù)到這個(gè)地址。如果要說清楚這個(gè)問題,我們就要結(jié)合匯編碼和一些計(jì)算機(jī)的體系結(jié)構(gòu)的知識來共同分析了。先來看testsigsegv.c的匯編碼:... ...main: !#PROLOGUE# 0 save %sp, -120, %sp !#PROLOGUE# 1 sethi %hi(4096), %i0 or %i0, 273, %i0 st %i0, [%fp-20] ld [%fp-20], %i1 mov 17, %i0 stb %i0, [%i1] nop ret restore... ...我們關(guān)注的是這句:stb %i0, [%i1]從計(jì)算機(jī)底層的執(zhí)行角度來說,過程是如何的呢?%i0寄存器里存儲的是立即數(shù)17,我們要將之存儲到寄存器%i1的值指向的內(nèi)存地址。這一過程對于CPU來說其指揮執(zhí)行的正常過程是:將寄存器%i0中的值送上數(shù)據(jù)總線,將寄存器%i1的值送到地址總線,然后使能控制總線上的寫信號完成這一向內(nèi)存寫1 byte數(shù)據(jù)的過程。我們再看testsigbus.c的匯編碼:... ...main: !#PROLOGUE# 0 save %sp, -120, %sp !#PROLOGUE# 1 sethi %hi(4096), %i0 or %i0, 273, %i0 st %i0, [%fp-20] ld [%fp-20], %i1 mov 17, %i0 st %i0, [%i1] nop ret restore... ...同樣最后一句:st %i0, [%i1],CPU執(zhí)行的過程與testsigsegv.c中的一致(只是要存儲數(shù)據(jù)長度是4字節(jié)),那為什么產(chǎn)生錯(cuò)誤的原因不同呢?一個(gè)是SIGSEGV,而另一個(gè)是SIGBUS。這里涉及到的就是對內(nèi)存地址的校驗(yàn)的問題了,包括對內(nèi)存地址是否對齊的校驗(yàn)以及該內(nèi)存地址是否合法的校驗(yàn)。我們假設(shè)如果首先進(jìn)行的內(nèi)存地址是否合法的校驗(yàn)(是否歸屬于用戶進(jìn)程的地址空間),那么我們回顧一下,這兩個(gè)程序中的地址0x00001111顯然都不合法,按照這種流程,兩個(gè)程序都應(yīng)該是SIGSEGV導(dǎo)致的core才對,但是事實(shí)并非如此。那難道是先校驗(yàn)內(nèi)存地址的對齊?我們再看這種思路是否合理?testsigsegv.c中,0x00001111這個(gè)地址值被賦給了char *pc;也就是告訴CPU通過這個(gè)地址我們要存取一個(gè)字節(jié)的值,對于一個(gè)字節(jié)長度的數(shù)據(jù),無所謂對齊,所以該地址通過對齊校驗(yàn);并被放到地址總線上了。而在testsigbus.c里,0x00001111這個(gè)地址值被賦給了int *pi;也就是告訴CPU通過這個(gè)地址我們要存取一個(gè)起碼4個(gè)字節(jié)的值,那么對于長度4個(gè)字節(jié)的對象,其存放地址起碼要被4整除才可以,而0x00001111這個(gè)值顯然不能滿足要求,也就不能通過內(nèi)存對齊的校驗(yàn)。也就是說SIGBUS這個(gè)信號在地址被放到地址總線之后被檢查出來的不符合對齊的錯(cuò)誤;而SIGSEGV則是在地址已經(jīng)放到地址總線上后,由后續(xù)流程中的某個(gè)設(shè)施檢查出來的內(nèi)存違法訪問錯(cuò)誤。一般我們平時(shí)遇到SIGBUS時(shí)總是因?yàn)榈刂肺磳R導(dǎo)致的,而SIGSEGV則是由于內(nèi)存地址不合法造成的。1) SIGBUS(Bus error)意味著指針?biāo)鶎?yīng)的地址是有效地址,但總線不能正常使用該指針。通常是未對齊的數(shù)據(jù)訪問所致。2) SIGSEGV(Segment fault)意味著指針?biāo)鶎?yīng)的地址是無效地址,沒有物理內(nèi)存對應(yīng)該地址。 Linux的mmap(2)手冊頁使用映射可能涉及到如下信號SIGSEGV 試圖對只讀映射區(qū)域進(jìn)行寫操作SIGBUS 試圖訪問一塊無文件內(nèi)容對應(yīng)的內(nèi)存區(qū)域,比如超過文件尾的內(nèi)存區(qū)域,或者以前有文件內(nèi)容對應(yīng),現(xiàn)在為另一進(jìn)程截?cái)噙^的內(nèi)存區(qū)域。調(diào)試方法:gcc -g 編譯 ulimit -c 20000 之后運(yùn)行程序,等core dump 最后gdb -c core
回答者:網(wǎng)友
產(chǎn)品精選
搜索問答
還沒有汽配人賬號?立即注冊

我要提問

汽配限時(shí)折扣

本頁是網(wǎng)友提供的關(guān)于“centos中出現(xiàn)sigsegv和sigbus錯(cuò)誤,怎么辦”的解答,僅供您參考,汽配人網(wǎng)不保證該解答的準(zhǔn)確性。