日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

Linux系統(tǒng)中找出并解決程序錯誤方法( 六 )


首先 , 將 Oops 消息保存在一個文件中以便通過 ksymoops 實用程序運(yùn)行它 。清單 10 顯示了由安裝 JFS 文件系統(tǒng)的 mount 命令創(chuàng)建的 Oops 消息 , 問題是由清單 8 中添加到 JFS 安裝代碼的那三行代碼產(chǎn)生的 。

CODE:ksymoops 2.4.0 on i686 2.4.17. Options used
... 15:59:37 sfb1 kernel: Unable to handle kernel NULL pointer dereference at
virtual address 0000000
... 15:59:37 sfb1 kernel: c01588fc
... 15:59:37 sfb1 kernel: *pde = 0000000
... 15:59:37 sfb1 kernel: Oops: 0000
... 15:59:37 sfb1 kernel: CPU: 0
... 15:59:37 sfb1 kernel: EIP: 0010:[jfs_mount 60/704]
... 15:59:37 sfb1 kernel: Call Trace: [jfs_read_super 287/688]
[get_sb_bdev 563/736] [do_kern_mount 189/336] [do_add_mount 35/208]
[do_page_fault 0/1264]
... 15:59:37 sfb1 kernel: Call Trace: []...
... 15:59:37 sfb1 kernel: [>EIP; c01588fc <=====
...
Trace; c0106cf3;
Code; c01588fc;
00000000 <_EIP>:
Code; c01588fc <=====
0: 8b 2d 00 00 00 00 mov 0x0,雙 <=====
Code; c0158902;
6: 55 push 雙

清單 10. ksymoops 處理后的 Oops 消息
接下來 , 您要確定 jfs_mount 中的哪一行代碼引起了這個問題 。Oops 消息告訴我們問題是由位于偏移地址 3c 的指令引起的 。做這件事的辦法之一是對 jfs_mount.o 文件使用 objdump 實用程序 , 然后查看偏移地址 3c 。Objdump 用來反匯編模塊函數(shù) , 看看您的 C 源代碼會產(chǎn)生什么匯編指令 。清單 11 顯示了使用 objdump 后您將看到的內(nèi)容 , 接著 , 我們查看 jfs_mount 的 C 代碼 , 可以看到空值是第 109 行引起的 。偏移地址 3c 之所以很重要 , 是因為 Oops 消息將該處標(biāo)識為引起問題的位置 。

CODE:109 printk("%dn",*ptr);
objdump jfs_mount.o
jfs_mount.o: file format elf32-i386
【Linux系統(tǒng)中找出并解決程序錯誤方法】Disassembly of section .text:
00000000 :
0:55 push 雙
...
2c: e8 cf 03 00 00 call 400;
31: 89 c3 mov 陎,離
33: 58 pop 陎
34: 85 db test 離,離
36: 0f 85 55 02 00 00 jne 291;
3c: 8b 2d 00 00 00 00 mov 0x0,雙 << problem line above
42: 55 push 雙

清單 11. jfs_mount 的匯編程序清單
kdb
Linux 內(nèi)核調(diào)試器(Linux kernel debugger , kdb)是 Linux 內(nèi)核的補(bǔ)丁 , 它提供了一種在系統(tǒng)能運(yùn)行時對內(nèi)核內(nèi)存和數(shù)據(jù)結(jié)構(gòu)進(jìn)行檢查的辦法 。請注意 , kdb 不需要兩臺機(jī)器 , 不過它也不允許您像 kgdb 那樣進(jìn)行源代碼級別上的調(diào)試 。您可以添加額外的命令 , 給出該數(shù)據(jù)結(jié)構(gòu)的標(biāo)識或地址 , 這些命令便可以格式化和顯示基本的系統(tǒng)數(shù)據(jù)結(jié)構(gòu) 。目前的命令集允許您控制包括以下操作在內(nèi)的內(nèi)核操作:
處理器單步執(zhí)行;
執(zhí)行到某條特定指令時停止;
當(dāng)存?。ɑ蛐薷模┠硞€特定的虛擬內(nèi)存位置時停止;
當(dāng)存取輸入/輸出地址空間中的寄存器時停止;
對當(dāng)前活動的任務(wù)和所有其它任務(wù)進(jìn)行堆棧回溯跟蹤(通過進(jìn)程 ID);
對指令進(jìn)行反匯編 。
追擊內(nèi)存溢出
您肯定不想陷入類似在幾千次調(diào)用之后發(fā)生分配溢出這樣的情形 。我們的小組花了許許多多時間來跟蹤稀奇古怪的內(nèi)存錯誤問題 。應(yīng)用程序在我們的開發(fā)工作站上能運(yùn)行 , 但在新的產(chǎn)品工作站上 , 這個應(yīng)用程序在調(diào)用 malloc() 兩百萬次之后就不能運(yùn)行了 。真正的問題是在大約一百萬次調(diào)用之后發(fā)生了溢出 。新系統(tǒng)之所有存在這個問題 , 是因為被保留的 malloc() 區(qū)域的布局有所不同 , 從而這些零散內(nèi)存被放置在了不同的地方 , 在發(fā)生溢出時破壞了一些不同的內(nèi)容 。
我們用多種不同技術(shù)來解決這個問題 , 其中一種是使用調(diào)試器 , 另一種是在源代碼中添加跟蹤功能 。在我職業(yè)生涯的大概也是這個時候 , 我便開始關(guān)注內(nèi)存調(diào)試工具 , 希望能更快更有效地解決這些類型的問題 。在開始一個新項目時 , 我最先做的事情之一就是運(yùn)行 MEMWATCH 和 YAMD , 看看它們是不是會指出內(nèi)存管理方面的問題 。

推薦閱讀