下載本文檔
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、簡而言之,產(chǎn)生段錯誤就是訪問了錯誤的內(nèi)存段,一般是你沒有權(quán)限,或者根本就不存在對應(yīng)的物理內(nèi)存,尤其常見的是訪問 0 地址一般來說,段錯誤就是指訪問的內(nèi)存超出了系統(tǒng)所給這個程序的內(nèi)存空間,通常這 個值是由 gdtr 來保存的,他是一個 48 位的寄存器,其中的 32 位是保存由它指向 的 gdt表,后 13 位保存相應(yīng)于 gdt 的下標(biāo),最后 3 位包括了程序是否在內(nèi)存中以 及程序的在cpu 中的運行級別,指向的 gdt 是由以 64 位為一個單位的表,在這張表 中就保存著程序運行的代碼段以及數(shù)據(jù)段的起始地址以及與此相應(yīng)的段限和頁面 交換還有程序運行級別還有內(nèi)存粒度等等的信息。一旦一個程序發(fā)生了
2、越界訪 問,cpu 就會產(chǎn)生相應(yīng)的異常保護(hù),于是 segmentation fault 就出現(xiàn)了 .在編程中以下幾類做法容易導(dǎo)致段錯誤,基本是是錯誤地使用指針引起的1) 訪問系統(tǒng)數(shù)據(jù)區(qū),尤其是往 系統(tǒng)保護(hù)的內(nèi)存地址寫數(shù)據(jù) 最常見就是給一個指針以 0地址2) 內(nèi)存越界(數(shù)組越界,變量類型不一致等)訪問到不屬于你的內(nèi)存區(qū)域 解決方法我們在用 C/C+語言寫程序的時侯,內(nèi)存管理的絕大部分工作都是需要我們來做 的。實際上,內(nèi)存管理是一個比較繁瑣的工作,無論你多高明,經(jīng)驗多豐富,難 免會在此處犯些小錯誤, 而通常這些錯誤又是那么的淺顯而易于消除。 但是手工 除蟲”(debug),往往是效率低下且讓人厭煩
3、的,本文將就段錯誤這個內(nèi)存訪問越界的錯誤談?wù)勅绾慰焖俣ㄎ贿@些段錯誤的語句。下面將就以下的一個存在段錯誤的程序介紹幾種調(diào)試方法:1 dummy_f un cti on (void)2 3 un sig ned char *ptr = 0 x00;4 *ptr = 0 x00;5 66 int main (void)7 8 dummy_fu ncti on ();109return 0;10 作為一個熟練的 C/C+程序員,以上代碼的 bug 應(yīng)該是很清楚的,因為它嘗試操 作地址為 0 的內(nèi)存區(qū)域,而這個內(nèi)存區(qū)域通常是不可訪問的禁區(qū),當(dāng)然就會出錯 了。我們嘗試編譯運行它:xiaosuoge ntu
4、x test $ ./a.out段錯誤果然不出所料,它出錯并退出了。1利用 gdb 逐步查找段錯誤:這種方法也是被大眾所熟知并廣泛采用的方法,首先我們需要一個帶有調(diào)試信息 的可執(zhí)行程序,所以我們加上 -g -rdyn amic的參數(shù)進(jìn)行編譯,然后用 gdb 調(diào)試運 行這個新編譯的程序,具體步驟如下:xiaosuoge ntux test $ gcc -g -rdyn amic d.cxiaosuoge ntux test $ gdb ./a.outGNU gdb 6.5Copyright (C) 2006 Free Software Fou ndatio n, I nc.GDB is free
5、 software, covered by the GNU Gen eral Public Lice nse, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type show copy ing to see the con diti ons.There is absolutely no warra nty for GDB. Type show warra nty for details.This GDB was con figured as i686-pc-l i
6、nu x-g nu .Us ing host libthread_db library/lib/libthread_db.so.1.(gdb) rStart ing program: /home/xiaosuo/test/a.outProgram received sig nal SIGSEGV, Segme ntati on fault.0 x08048524 in dummy_fu nction () at d.c:44 *ptr = 0 x00;(gdb)哦?!好像不用一步步調(diào)試我們就找到了出錯位置 d.c 文件的第 4 行,其實就是 如此的簡單。從這里我們還發(fā)現(xiàn)進(jìn)程是由于收到了 SIG
7、SEGV 信號而結(jié)束的。通 過進(jìn)一步的查閱文檔(man 7 signal),我們知道 SIGSEGV 默認(rèn) handler 的動作是打 印”段錯誤的出錯信息,并產(chǎn)生 Core 文件,由此我們又產(chǎn)生了方法二。2.分析 Core 文件:Core 文件是什么呢?The default action of certa in sig nals is to cause a process to term in ate and producea core dump file, a disk file containing an image of the processs memory at the time
8、 oftermin ati on. A list of the sig nals which cause a process to dump core can be found insig nal(7).以上資料摘自 man page(man 5 core。不過奇怪了,我的系統(tǒng)上并沒有找到core文件。后來,憶起為了漸少系統(tǒng)上的拉圾文件的數(shù)量(本人有些潔癖,這也是我喜歡 Gen too 的原因之一),禁止了 core 文件的生成,查看了以下果真如此,將 系統(tǒng)的 core 文件的大小限制在 512K 大小,再試:xiaosuoge ntux test $ ulimit -c xiaosuoge
9、ntux test $ ulimit -c 1000 xiaosuogentux test $ ulimit -c 1000 xiaosuoge ntux test $ ./a.out段錯誤 (core dumped) xiaosuoge ntux test $ lsa.out core d.c f.c g.c pan go.c test_ic onv.c test_regex.ccore 文件終于產(chǎn)生了,用 gdb 調(diào)試一下看看吧:xiaosuoge ntux test $ gdb ./a.out coreGNU gdb 6.5Copyright (C) 2006 Free Software
10、 Fou ndatio n, I nc.GDB is free software, covered by the GNU Gen eral Public Lice nse, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type show copy ing to see the con diti ons.There is absolutely no warra nty for GDB. Type show warra nty for details.This GDB
11、 was con figured as i686-pc-l inu x-g nu .Us ing host libthread_db library/lib/libthread_db.so.1.warning: Cant read path name for load map 輸入 / 輸出錯誤.Read ing symbols from /lib/libc.so.6.d one.Loaded symbols for /lib/libc.so.6Read ing symbols from /lib/ld-li nu x.so.2.d one.Loaded symbols for /lib/ld
12、-l inu x.so.2Core was gen erated by ./a.out.Program term in ated with sig nal 11, Segme ntati on fault.#0 0 x08048524 in dummy_fu nction () at d.c:44 *ptr = 0 x00;哇,好歷害,還是一步就定位到了錯誤所在地,佩服一下Linux/Unix 系統(tǒng)的此類設(shè)計。接著考慮下去,以前用 windows 系統(tǒng)下的 ie 的時侯,有時打開某些網(wǎng)頁,會出現(xiàn)運行時錯誤”這個時侯如果恰好你的機(jī)器上又裝有windows 的編譯器的話,他會彈出來一個對話框,問你
13、是否進(jìn)行調(diào)試,如果你選擇是,編譯器將 被打開,并進(jìn)入調(diào)試狀態(tài),開始調(diào)試。Linux 下如何做到這些呢?我的大腦飛速地旋轉(zhuǎn)著,有了,讓它在 SIGSEGV 的 handler 中調(diào)用 gdb,于是第三個方法又誕 生了:3.段錯誤時啟動調(diào)試:#i nclude #i nclude #in elude #include void dump(i nt sig no)char buf1024;char cmd1024;FILE *fh;snprin tf(buf, sizeof(buf), /proc/%d/cmdli ne, getpid(); if(!(fh = fope n(buf, r)exit
14、(0);if(!fgets(buf, sizeof(buf), fh)exit(0);fclose(fh);if(bufstrlen(buf) - 1 = n)bufstrle n( buf) - 1 = 0;snprin tf(cmd, sizeof(cmd), gdb %s %d, buf, getpid(); system(cmd);exit(0);voiddummy_fu nction (void)un sig ned char *ptr = 0 x00;*ptr = 0 x00;intmain (void)sig nal(SIGSEGV, & dump); dummy_fu
15、nctio n ();return 0;編譯運行效果如下:xiaosuoge ntux test $ gcc -g -rdyn amic f.cxiaosuoge ntux test $ ./a.outGNU gdb 6.5Copyright (C) 2006 Free Software Fou ndatio n, I nc.GDB is free software, covered by the GNU Gen eral Public Lice nse, and you arewelcome to change it and/or distribute copies of it under
16、certain conditions.Type show copy ing to see the con diti ons.There is absolutely no warra nty for GDB. Type show warra nty for details.This GDB was con figured as i686-pc-l inu x-g nu .Us ing host libthread_db library/lib/libthread_db.so.1.Attachi ng to program: /home/xiaosuo/test/a.out, process 95
17、63Read ing symbols from /lib/libc.so.6.d one.Loaded symbols for /lib/libc.so.6Read ing symbols from /lib/ld-li nu x.so.2.d one.Loaded symbols for /lib/ld-l inu x.so.2 0 xffffe410 in _kernel_vsyscall () (gdb) bt#0 0 xffffe410 in _kernel_vsyscall ()#1 0 xb7ee4b53 in waitpid () from /lib/libc.so.6#2 0
18、xb7e925c9 in strtold()from /lib/libc.so.6#3 0 x08048830 in dump (signo=11) at f.c:22#4 #5 0 x0804884c in dummy_fu nction () at f.c:31#6 0 x08048886 in main () at f.c:38怎么樣?是不是依舊很酷?以上方法都是在系統(tǒng)上有 gdb 的前提下進(jìn)行的,如果沒有呢?其實 glibc 為我們 提供了此類能夠 dump 棧內(nèi)容的函數(shù)簇,詳見/usr/include/execinfo.h (這些函數(shù)都 沒有提供man page 難怪我們找不到),另
19、外你也可以通過 gnu 的手冊進(jìn)行學(xué) 習(xí)。4.禾 U 用 backtrace 和 objdump 進(jìn)行分析:重寫的代碼如下:#i nclude #i nclude #i nclude #in elude /* A dummy fun ctio n to make the backtrace more in terest ing. */ voiddummy_fu nction (void)un sig ned char *ptr = 0 x00;*ptr = 0 x00;void dump(i nt sig no)void *array10;size_t size;char *stri ngs;size_t i;size = backtrace (array, 10);stri ngs = backtrace_symbols (array, size);printf (Obta ined %zd stack frames.n, size);for (i = 0; i size; i+)printf (%sn, stringsi);free (stri ngs);exit(0);intmain (void)sig nal(SIGSEGV, & dum
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2026山東濱州市市屬事業(yè)單位招聘備考考試試題及答案解析
- 2026貴州貴陽禮物旅游產(chǎn)業(yè)發(fā)展有限公司招聘1人筆試備考試題及答案解析
- 2026山東淄博桓臺縣面向退役大學(xué)生士兵專項崗位招聘考試參考試題及答案解析
- 2026廣東佛山順德區(qū)杏壇鎮(zhèn)林文恩中學(xué)招聘臨聘教師4人備考考試試題及答案解析
- 2026江蘇連云港興榆創(chuàng)業(yè)投資有限公司對外招聘崗位開考情況說明筆試備考題庫及答案解析
- 2026年長春大學(xué)公開招聘博士高層次人才1號(50人)筆試參考題庫及答案解析
- 2026天津南開區(qū)教育系統(tǒng)招聘170人(含高層次人才)備考考試題庫及答案解析
- 2026云南嘉華食品有限公司招聘考試備考試題及答案解析
- 2026年上半年浙江杭州市婦產(chǎn)科醫(yī)院(杭州市婦幼保健院)高層次、緊缺專業(yè)人才招聘15人(總)備考考試試題及答案解析
- 2026年度淄博高新區(qū)事業(yè)單位面向退役大學(xué)生士兵公開招聘綜合類(專項)崗位工作人員備考考試試題及答案解析
- 南京醫(yī)科大學(xué)2026年招聘人事代理人員備考題庫及1套參考答案詳解
- 2026年教育平臺資源輸出協(xié)議
- 【《四旋翼飛行器坐標(biāo)系及相互轉(zhuǎn)換關(guān)系分析綜述》1000字】
- 2026浙江金華市婺城區(qū)城市發(fā)展控股集團(tuán)有限公司招聘59人筆試參考題庫及答案解析
- 靜脈補(bǔ)液課件
- 廣東深圳市鹽田高級中學(xué)2024~2025學(xué)年高一上冊1月期末考試化學(xué)試題 附答案
- 2026年輔警招聘考試試題庫附答案【完整版】
- 建筑施工風(fēng)險辨識與防范措施
- 浙江省杭州地區(qū)六校2026屆化學(xué)高一第一學(xué)期期末學(xué)業(yè)水平測試試題含解析
- 2025年CFA二級估值與財務(wù)報表分析試卷(含答案)
- 2025年宜昌化學(xué)真題試卷及答案
評論
0/150
提交評論