最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux平臺(tái)Segmentation fault(段錯(cuò)誤)調(diào)試過程

 更新時(shí)間:2023年09月04日 09:40:08   作者:good-destiny  
這篇文章主要介紹了Linux平臺(tái)Segmentation fault(段錯(cuò)誤)調(diào)試過程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

1. 段錯(cuò)誤是什么

一句話來說,段錯(cuò)誤是指訪問的內(nèi)存超出了系統(tǒng)給這個(gè)程序所設(shè)定的內(nèi)存空間,

例如訪問了不存在的內(nèi)存地址、訪問了系統(tǒng)保護(hù)的內(nèi)存地址、訪問了只讀的內(nèi)存地址等等情況。

2. 段錯(cuò)誤的原因

段錯(cuò)誤,英文segmentation fault

段錯(cuò)誤的定義 

segementation fault (often shortened to segfault) or access violation
often raised by hardware with memory protection, notifying an operation system(OS) the software has attempted to access a restricted area of memory.

段錯(cuò)誤常見于提供低級(jí)別的內(nèi)存訪問機(jī)制(如C語言)的語言程序中,通常由非法訪問導(dǎo)致,即錯(cuò)誤地使用指針訪問虛擬內(nèi)存。

原因列舉

  • 對(duì)空指針賦值——由內(nèi)存管理硬件所導(dǎo)致
  • 嘗試去訪問一個(gè)不存在的內(nèi)存地址(超出進(jìn)程分配的地址)
  • 嘗試去訪問程序無權(quán)限訪問的地址(如進(jìn)程上下文中的內(nèi)核結(jié)構(gòu)(kernel structures))
  • 嘗試去訪問只讀的內(nèi)存(如代碼段)

對(duì)應(yīng)著程序中的情況分別為:

  • 引用或者賦值一個(gè)為初始化的指針(野指針(wild pointer),隨機(jī)指向一個(gè)內(nèi)存地址)
  • 引用或者賦值一個(gè)已經(jīng)被free的指針(dangling pointer,指向一個(gè)已經(jīng)被freed/deallocated/deleted的內(nèi)存地址)
  • A buffer overflow
  • A stack overflow

3. 段錯(cuò)誤信息的獲取

3.1 dmesg

dmesg可以在應(yīng)用程序crash掉時(shí),顯示內(nèi)核中保存的相關(guān)信息。

如下所示,通過dmesg命令可以查看發(fā)生段錯(cuò)誤的程序名稱、引起段錯(cuò)誤發(fā)生的內(nèi)存地址、指令指針地址、堆棧指針地址、錯(cuò)誤代碼、錯(cuò)誤原因等。

3.2 -g

使用gcc編譯程序的源碼時(shí),加上-g參數(shù),這樣可以使得生成的二進(jìn)制文件中加入可以用于gdb調(diào)試的有用信息。

3.3 nm

使用nm命令列出二進(jìn)制文件中的符號(hào)表,包括符號(hào)地址、符號(hào)類型、符號(hào)名等,這樣可以幫助定位在哪里發(fā)生了段錯(cuò)誤。

3.4 ldd

使用ldd命令查看二進(jìn)制程序的共享鏈接庫依賴,包括庫的名稱、起始地址,這樣可以確定段錯(cuò)誤到底是發(fā)生在了自己的程序中還是依賴的共享庫中。

4. 段錯(cuò)誤的調(diào)試方法

4.1 使用gcc和gdb

4.1.1 調(diào)試步驟

為了能夠使用gdb調(diào)試程序,在編譯階段加上-g參數(shù),以程序segfault3.c為例。

root@twq2018:~/segfault$ gcc -g -o segfault3 segfault3.c
root@twq2018:~/segfault$ gdb ./segfault3
(gdb) run
Starting program: /home/twq/segfault/segfault3 
Program received signal SIGSEGV, Segmentation fault.
0x001a306a in memcpy () from /lib/tls/i686/cmov/libc.so.6
(gdb)

從輸出看出,程序segfault3.c收到SIGSEGV信號(hào),觸發(fā)段錯(cuò)誤,并提示地址0x001a306a、調(diào)用memcpy報(bào)的錯(cuò),位于/lib/tls/i686/cmov/libc.so.6庫中。

4.1.2 適用場(chǎng)景

1、僅當(dāng)能確定程序一定會(huì)發(fā)生段錯(cuò)誤的情況下使用。

2、當(dāng)程序的源碼可以獲得的情況下,使用-g參數(shù)編譯程序。

3、一般用于測(cè)試階段,生產(chǎn)環(huán)境下gdb會(huì)有副作用:使程序運(yùn)行減慢,運(yùn)行不夠穩(wěn)定,等等。

4、即使在測(cè)試階段,如果程序過于復(fù)雜,gdb也不能處理。

4.2 使用gdb和core文件

在4.1節(jié)中提到段錯(cuò)誤會(huì)觸發(fā)SIGSEGV信號(hào),通過man 7 signal,可以看到SIGSEGV默認(rèn)的handler會(huì)打印段錯(cuò)誤出錯(cuò)信息,并產(chǎn)生core文件,由此我們可以借助于程序異常退出時(shí)生成的core文件中的調(diào)試信息。

使用gdb工具來調(diào)試程序中的段錯(cuò)誤,用bt命令查看backtrace以檢查發(fā)生程序運(yùn)行到哪里, 來定位core dump的文件->行.。

4.2.1 調(diào)試步驟

1、在一些Linux版本下,默認(rèn)是不產(chǎn)生core文件的,首先可以查看一下系統(tǒng)core文件的大小限制:

root@twq2018:~/segfault$ ulimit -c
0

2、可以看到默認(rèn)設(shè)置情況下,本機(jī)Linux環(huán)境下發(fā)生段錯(cuò)誤時(shí)不會(huì)自動(dòng)生成core文件,下面設(shè)置下core文件的大小限制(單位為KB),其中使用ulimit  -c unlimited來設(shè)置無限大,則任意情況下都會(huì)產(chǎn)生core文件。

root@twq2018:~/segfault$ ulimit -c 1024
root@twq2018:~/segfault$ ulimit -c
1024

3、運(yùn)行程序segfault3.c,發(fā)生段錯(cuò)誤生成core文件:

root@twq2018:~/segfault$ ./segfault3
段錯(cuò)誤 (core dumped) 

4、加載core文件,使用gdb工具進(jìn)行調(diào)試:

root@twq2018:~/segfault$ gdb ./segfault3 ./core 

4.2.2 適用場(chǎng)景

1、適合于在實(shí)際生成環(huán)境下調(diào)試程序的段錯(cuò)誤(即在不用重新發(fā)生段錯(cuò)誤的情況下重現(xiàn)段錯(cuò)誤)。

2、當(dāng)程序很復(fù)雜,core文件相當(dāng)大時(shí),該方法不可用。

4.3 使用objdump

4.3.1 調(diào)試步驟

1、使用dmesg命令,找到最近發(fā)生的段錯(cuò)誤輸出信息:

root@twq2018:~/segfault$ dmesg
... ...
[17257.502808] segfault3[3320]: segfault at 80484e0 ip 0018506a sp bfc1cd6c error 7 in libc-2.10.1.so[110000+13e000]

其中,對(duì)我們接下來的調(diào)試過程有用的是發(fā)生段錯(cuò)誤的地址:80484e0和指令指針地址:0018506a。

2、使用objdump生成二進(jìn)制的相關(guān)信息,重定向到文件中:

root@twq2018:~/segfault$ objdump -d ./segfault3 > segfault3Dump

其中,生成的segfault3Dump文件中包含了二進(jìn)制文件的segfault3的匯編代碼。

3、在segfault3Dump文件中查找發(fā)生段錯(cuò)誤的地址:

root@twq2018:~/segfault$ grep -n -A 10 -B 10 "80484e0" ./segfault3Dump 
121- 80483df:    ff d0                    call   *%eax
122- 80483e1:    c9                       leave  
123- 80483e2:    c3                       ret    
124- 80483e3:    90                       nop
125-
126-080483e4 <main>:
127- 80483e4:    55                       push   %ebp
128- 80483e5:    89 e5                    mov    %esp,%ebp
129- 80483e7:    83 e4 f0                 and    $0xfffffff0,%esp
130- 80483ea:    83 ec 20                 sub    $0x20,%esp
131: 80483ed:    c7 44 24 1c e0 84 04     movl   $0x80484e0,0x1c(%esp)
132- 80483f4:    08 
133- 80483f5:    b8 e5 84 04 08           mov    $0x80484e5,%eax
134- 80483fa:    c7 44 24 08 05 00 00     movl   $0x5,0x8(%esp)
135- 8048401:    00 
136- 8048402:    89 44 24 04              mov    %eax,0x4(%esp)
137- 8048406:    8b 44 24 1c              mov    0x1c(%esp),%eax
138- 804840a:    89 04 24                 mov    %eax,(%esp)
139- 804840d:    e8 0a ff ff ff           call   804831c <memcpy@plt>
140- 8048412:    c9                       leave  
141- 8048413:    c3                       ret   

通過對(duì)以上匯編代碼分析,得知段錯(cuò)誤發(fā)生main函數(shù),對(duì)應(yīng)的匯編指令是movl $0x80484e0,0x1c(%esp),接下來打開程序的源碼,找到匯編指令對(duì)應(yīng)的源碼,也就定位到段錯(cuò)誤了。 

4.3.2 適用場(chǎng)景

1、不需要-g參數(shù)編譯,不需要借助于core文件,但需要有一定的匯編語言基礎(chǔ)。

2、如果使用了gcc編譯優(yōu)化參數(shù)(-O1,-O2,-O3)的話,生成的匯編指令將會(huì)被優(yōu)化,使得調(diào)試過程有些難度。

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Linux網(wǎng)絡(luò)--傳輸層--TCP協(xié)議基礎(chǔ)詳解

    Linux網(wǎng)絡(luò)--傳輸層--TCP協(xié)議基礎(chǔ)詳解

    這篇文章主要介紹了Linux網(wǎng)絡(luò)--傳輸層--TCP協(xié)議基礎(chǔ),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • Linux如何啟動(dòng)SELinux

    Linux如何啟動(dòng)SELinux

    這篇文章主要介紹了Linux如何啟動(dòng)SELinux問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-02-02
  • Redhat 7/CentOS 7 SSH 免密登錄的方法

    Redhat 7/CentOS 7 SSH 免密登錄的方法

    本篇文章主要介紹了Redhat 7/CentOS 7 SSH 免密登錄的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-03-03
  • CentOS7掛載新數(shù)據(jù)盤的完整步驟

    CentOS7掛載新數(shù)據(jù)盤的完整步驟

    這篇文章主要給大家介紹了關(guān)于CentOS7掛載新數(shù)據(jù)盤的完整步驟,文中通過示例代碼將實(shí)現(xiàn)的步驟介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用CentOS7具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Linux編輯器之vim使用詳解

    Linux編輯器之vim使用詳解

    介紹Linuxyum軟件包管理器的安裝、更新、刪除、搜索及緩存清理命令,詳解vim的三種模式(普通/插入/末行)操作技巧,包括光標(biāo)移動(dòng)、文本編輯、保存退出等,并提及配置文件的使用方法
    2025-09-09
  • linux中$符號(hào)的基礎(chǔ)用法總結(jié)

    linux中$符號(hào)的基礎(chǔ)用法總結(jié)

    這篇文章主要給大家介紹了關(guān)于linux中$符號(hào)的基礎(chǔ)用法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用linux系統(tǒng)具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • 配置XManager5連接Linux圖形化界面詳解

    配置XManager5連接Linux圖形化界面詳解

    這篇文章主要介紹了配置XManager5連接Linux圖形化界面詳解,需要的朋友可以參考下
    2017-01-01
  • centos 7 修改sshd | 禁止 root登錄及sshd端口腳本定義

    centos 7 修改sshd | 禁止 root登錄及sshd端口腳本定義

    這篇文章主要介紹了centos 7 修改sshd | 禁止 root登錄及sshd端口腳本定義,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Memcached 分布式緩存實(shí)現(xiàn)原理簡介

    Memcached 分布式緩存實(shí)現(xiàn)原理簡介

    這篇文章主要介紹了Memcached 分布式緩存實(shí)現(xiàn)原理簡介,具有參考價(jià)值,需要的朋友可以參考下。
    2016-06-06
  • ubuntu制作本地源的實(shí)現(xiàn)方法

    ubuntu制作本地源的實(shí)現(xiàn)方法

    下面小編就為大家?guī)硪黄猽buntu制作本地源的實(shí)現(xiàn)方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12

最新評(píng)論

凯里市| 大理市| 昌平区| 五常市| 闸北区| 盖州市| 邓州市| 苏尼特右旗| 察雅县| 恩平市| 麟游县| 隆回县| 阜宁县| 公安县| 会东县| 青河县| 永和县| 海南省| 天镇县| 霍邱县| 大余县| 玉树县| 阿拉尔市| 淅川县| 浦东新区| 福泉市| 边坝县| 大名县| 邢台县| 阳西县| 木兰县| 遵化市| 前郭尔| 若羌县| 巧家县| 玉门市| 山丹县| 南丹县| 武夷山市| 峨眉山市| 逊克县|