




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、Linux下的段錯(cuò)誤(Segmentation fault )產(chǎn)生的原因及調(diào)試方法(經(jīng)典)2009-04-05 11:25簡而言之,產(chǎn)生段錯(cuò)誤就是訪問了錯(cuò)誤的內(nèi)存段,一般是你沒有權(quán)限,或者根本就不 存在對應(yīng)的物理內(nèi)存,尤其常見的是訪問0地址.一般來說,段錯(cuò)誤就是指訪問的內(nèi)存超出了系統(tǒng)所給這個(gè)程序的內(nèi)存空間,通常這個(gè)值是由gdtr來保存的,他是一個(gè)48位的寄存器,其中的32位是保存由它指向的gdt表,后13位保存相應(yīng)于gdt的下標(biāo),最后3位包括了程序是否在內(nèi)存中以及程序的在cpu中的運(yùn)行級別,指向的gdt是由以64位為一個(gè)單位的表,在這張表中就保存著程序運(yùn)行的代碼段以及數(shù)據(jù)段的起始地址以及與此相
2、應(yīng)的段限和頁面交換還有程序運(yùn)行級別還有內(nèi)存粒度等等的信息。一旦一個(gè)程序發(fā)生了越界訪問,cpu就會產(chǎn)生相應(yīng)的異常保護(hù),于是segmentation fault就出現(xiàn)了 在編程中以下幾類做法容易導(dǎo)致段錯(cuò)誤,基本是是錯(cuò)誤地使用指針引起的1)訪問系統(tǒng)數(shù)據(jù)區(qū),尤其是往系統(tǒng)保護(hù)的內(nèi)存地址寫數(shù)據(jù)最常見就是給一個(gè)指針以0地址2)內(nèi)存越界(數(shù)組越界,變量類型不一致等)訪問到不屬于你的內(nèi)存區(qū)域解決方法我 們在用C/C+語言寫程序的時(shí)侯,內(nèi)存管理的絕大部分工作都是需要我們來做的。實(shí)際上,內(nèi)存管理是一個(gè)比較繁瑣的工作,無論你多高明,經(jīng)驗(yàn)多豐富,難免會在此處犯些小錯(cuò)誤,而通常這些錯(cuò)誤又是那么的淺顯而易于消除。但是手工除
3、蟲”(debug),往往是效率低下且讓人厭煩的,本文將就”段錯(cuò)誤”這個(gè) 內(nèi)存訪問越界的錯(cuò)誤談?wù)勅绾慰焖俣ㄎ贿@些"段錯(cuò)誤”的語句。下面將就以下的一個(gè)存在段錯(cuò)誤的程序介紹幾種調(diào)試方法:1 dummy_function (void)2 3 unsigned char *ptr = 0x00;4 *ptr = 0x00;5 67 int main (void)8 9dummy_function ();1011return 0;12 作為一個(gè)熟練的 C/C+程序員,以上代碼的bug應(yīng)該是很清楚的,因?yàn)樗鼑L試操作地址為0的內(nèi)存區(qū)域,而這個(gè)內(nèi)存區(qū)域通常是不可訪問的禁區(qū),當(dāng)然就會出錯(cuò)了。我們嘗試編譯
4、運(yùn)行它:xiaosuogentux test $ ./a.out段錯(cuò)誤果然不出所料,它出錯(cuò)并退出了。1. 利用gdb逐步查找段錯(cuò)誤:這種方法也是被大眾所熟知并廣泛采用的方法,首先我們需要一個(gè)帶有調(diào)試信息的可執(zhí)行程序,所以我們加上-g -rdynamic"的參數(shù)進(jìn)行編譯,然后用 gdb調(diào)試運(yùn)行這個(gè)新編譯的程序,具體步驟如下:xiaosuogentux test $ gcc -g -rdynamic d.cxiaosuogentux test $ gdb ./a.outGNU gdb 6.5Copyright (C) 2006 Free Software Foundation, Inc.
5、GDB is free software, covered by the GNU General Public License, and you arewelcome to change it and/or distribute copies of it under certain conditions.Type "show copying" to see the conditions.There is absolutely no warranty for GDB. Type "show warranty" for details.This GDB wa
6、s configured as "i686-pc-linux-gnu".Using host libthread_db library "/lib/libthread_db.so.1".(gdb) rStarting program: /home/xiaosuo/test/a.outProgram received signal SIGSEGV, Segmentation fault.0x08048524 in dummy_function () at d.c:44*ptr = 0x00;(gdb)哦?!好像不用一步步調(diào)試我們就找到了出錯(cuò)位置d.c文件的
7、第4行,其實(shí)就是如此的簡單。從這里我們還發(fā)現(xiàn)進(jìn)程是由于收到了SIGSEGV信號而結(jié)束的。通過進(jìn)一步的查閱文檔(man 7signal),我們知道SIGSEGV默認(rèn)handler的動作是打印"段錯(cuò)誤”的出錯(cuò)信息,并產(chǎn)生 Core文 件,由此我們又產(chǎn)生了方法二。2. 分析Core文件:Core文件是什么呢?The default action of certain signals is to cause a process to terminate and produce a core dump file, a disk file containing an image of the p
8、rocess's memory at the time of termination. A list of the signals which cause a process to dump core can be found in signal(7).以 上資料摘自man page(man 5 core)。不過奇怪了,我的系統(tǒng)上并沒有找到core文件。后來,憶起為了漸少系統(tǒng)上的拉圾文件的數(shù)量(本人有些潔癖,這也是我喜歡Gen too的原因之一),禁止了 core文件的生成,查看了以下果真如此, 將系統(tǒng)的core文件的大小限制在512K大小, 再試:xiaosuogentux test
9、 $ ulimit -c0xiaosuogentux test $ ulimit -c 1000xiaosuogentux test $ ulimit -c1000xiaosuogentux test $ ./a.out段錯(cuò)誤(core dumped)xiaosuogentux test $ lsa.out core d.c f.c g.c pango.c test_iconv.c test_regex.ccore文件終于產(chǎn)生了,用 gdb調(diào)試一下看看吧:xiaosuogentux test $ gdb ./a.out coreGNU gdb 6.5Copyright (C) 2006 Fre
10、e Software Foundation, Inc.GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions.Type "show copying" to see the conditions.There is absolutely no warranty for GDB. Type "show warranty&q
11、uot; for details.This GDB was configured as "i686-pc-linux-gnu".Using host libthread_db library "/lib/libthread_db.so.1".warning: Can't read pathname for load map: 輸入/輸出錯(cuò)誤.Reading symbols from /lib/libc.so.6.done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-l
12、inux.so.2.done.Loaded symbols for /lib/ld-linux.so.2Core was generated by './a.out'.Program terminated with signal 11, Segmentation fault.#0 0x08048524 in dummy_function () at d.c:44*ptr = 0x00;哇,好歷害,還是一步就定位到了錯(cuò)誤所在地,佩服一下Linux/Unix系統(tǒng)的此類設(shè)計(jì)。接著考慮下去,以前用windows系統(tǒng)下的ie的時(shí)侯,有時(shí)打開某些網(wǎng)頁,會出現(xiàn)運(yùn)行時(shí)錯(cuò)誤”這個(gè)時(shí)侯如果恰好你的
13、機(jī)器上又裝有windows的編譯器的話,他會彈出來一個(gè)對話框,問你是否進(jìn)行調(diào)試,如果你選擇是,編譯器將被打開,并進(jìn)入調(diào)試狀態(tài),開始調(diào)試。Linux下如何做到這些呢?我的大腦飛速地旋轉(zhuǎn)著,有了,讓它在SIGSEGV的handler中調(diào)用gdb,于是第三個(gè)方法又誕生了:3.段錯(cuò)誤時(shí)啟動調(diào)試:#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <string.h>void dump(int signo)char buf1024;char cmd1024;FILE *fh;sn
14、printf(buf, sizeof(buf), "/proc/%d/cmdline", getpid();if(!(fh = fope n(buf, "r")exit(0);if(!fgets(buf, sizeof(buf), fh)exit(0);fclose(fh);if(bufstrlen(buf) - 1 = 'n')bufstrlen(buf) - 1 = '0:snprintf(cmd, sizeof(cmd), "gdb %s %d", buf, getpid();system(cmd);ex
15、it(0);voiddummy_function (void)unsigned char *ptr = 0x00;*ptr = 0x00;intmain (void)signal(SIGSEGV, & dump);dummy_function ();return 0;編譯運(yùn)行效果如下:xiaosuogentux test $ gcc -g -rdynamic f.cxiaosuogentux test $ ./a.outGNU gdb 6.5Copyright (C) 2006 Free Software Foundation, Inc.GDB is free software, co
16、vered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions.Type "show copying" to see the conditions.There is absolutely no warranty for GDB. Type "show warranty" for details.This GDB was configured as "i
17、686-pc-linux-gnu".Using host libthread_db library "/lib/libthread_db.so.1".Attaching to program: /home/xiaosuo/test/a.out, process 9563Reading symbols from /lib/libc.so.6.done.Loaded symbols for /lib/libc.so.6Reading symbols from /lib/ld-linux.so.2.done.Loaded symbols for /lib/ld-linu
18、x.so.20xffffe410 in _kernel_vsyscall ()(gdb) bt#0 0xffffe410 in _kernel_vsyscall ()#1 0xb7ee4b53 in waitpid () from /lib/libc.so.6#2 0xb7e925c9 in strtold()from /lib/libc.so.6#3 0x08048830 in dump (signo=11) at f.c:22#4 vsignal handler called#5 0x0804884c in dummy_function () at f.c:31#6 0x08048886
19、in main () at f.c:38怎么樣?是不是依舊很酷?以上方法都是在系統(tǒng)上有g(shù)db的前提下進(jìn)行的,如果沒有呢?其實(shí)glibc為我們提供了此類能夠dump棧內(nèi)容的函數(shù)簇,詳見/usr/include/execinfo.h (這些函數(shù)都沒有提供man page,難怪我們找不到),另外你也可以通過gnu的手冊進(jìn)行學(xué)習(xí)。4.利用backtrace和objdump進(jìn)行分析:重寫的代碼如下:#include <execinfo.h>#include <stdio.h>#include <stdlib.h>#include <signal.h>/*
20、A dummy function to make the backtrace more interesting. */voiddummy_function (void)unsigned char *ptr = 0x00;*ptr = 0x00; void dump(int signo)void *array10;size_t size;char *strings;size_t i;size = backtrace (array, 10);strings = backtrace_symbols (array, size); printf ("Obtained %zd stack frames.'n", size);for (i = 0; i < size; i+)printf ("%sn", stringsi);free (strings);exit(0);intmain (void)signal(SIGSEGV, &
溫馨提示
- 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)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年企業(yè)財(cái)務(wù)培訓(xùn)新方案:以員工基礎(chǔ)知識培養(yǎng)為核心
- 會所廚師合同范例
- 2025年硫精砂項(xiàng)目合作計(jì)劃書
- 農(nóng)村廢棄大坑合同范本
- 包裝蔬菜合同范本
- 農(nóng)用禮品贈送合同范本
- 企業(yè) 個(gè)人借貸合同范本
- 勞務(wù)派遣合同范本新
- 古建勞務(wù)生產(chǎn)合同范本
- 農(nóng)村房屋購買合同范本
- 春節(jié)后復(fù)工安全教育培訓(xùn)
- 提高發(fā)票額度的合同6篇
- 車站信號自動控制(第二版) 課件 -3-6502部分
- 2024安徽教師統(tǒng)一招聘考試《小學(xué)英語》試卷真題及答案
- 2024年考研數(shù)學(xué)(一)試題卷及答案
- 尼康NikonCOOLPIXP500數(shù)碼相機(jī)(中文)說明書
- TPO防水卷材在商業(yè)建筑屋面施工方案
- 2024解析:第九章大氣壓強(qiáng)-基礎(chǔ)練(解析版)
- 《會展概述》課件
- 外貿(mào)跟單工作規(guī)劃
- 火電廠汽機(jī)專業(yè)技術(shù)培訓(xùn)
評論
0/150
提交評論