日本a√视频在线,久久青青亚洲国产,亚洲一区欧美二区,免费g片在线观看网站

        <style id="k3y6c"><u id="k3y6c"></u></style>
        <s id="k3y6c"></s>
        <mark id="k3y6c"></mark>
          
          

          <mark id="k3y6c"></mark>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > Linux內(nèi)核調(diào)試器內(nèi)幕3

          Linux內(nèi)核調(diào)試器內(nèi)幕3

          ——
          作者: 時間:2007-04-18 來源:電子產(chǎn)品世界 收藏
          [size=18:ff78191c7b][b] 第 1 種情況:內(nèi)存調(diào)試工具[/b[/size:ff78191c7b]]
          C 語言作為 Linux 系統(tǒng)上標(biāo)準(zhǔn)的編程語言給予了我們對動態(tài)內(nèi)存分配很大的控制權(quán)。然而,這種自由可能會導(dǎo)致嚴(yán)重的內(nèi)存管理問題,而這些問題可能導(dǎo)致程序崩潰或隨時間的推移導(dǎo)致性能降級。
          內(nèi)存泄漏(即 malloc() 內(nèi)存在對應(yīng)的 free() 調(diào)用執(zhí)行后永不被釋放)和緩沖區(qū)溢出(例如對以前分配到某數(shù)組的內(nèi)存進(jìn)行寫操作)是一些常見的問題,它們可能很難檢測到。這一部分將討論幾個調(diào)試工具,它們極大地簡化了檢測和找出內(nèi)存問題的過程。
          [color=blue:ff78191c7b]MEMWATCH[/color:ff78191c7b]
          MEMWATCH 由 Johan Lindh 編寫,是一個開放源代碼 C 語言內(nèi)存錯誤檢測工具,您可以自己下載它(請參閱本文后面部分的參考資料)。只要在代碼中添加一個頭文件并在 gcc 語句中定義了 MEMWATCH 之后,您就可以跟蹤程序中的內(nèi)存泄漏和錯誤了。MEMWATCH 支持 ANSI C,它提供結(jié)果日志紀(jì)錄,能檢測雙重釋放(double-free)、錯誤釋放(erroneous free)、沒有釋放的內(nèi)存(unfreed memory)、溢出和下溢等等。
          清單 1. 內(nèi)存樣本(test1.c) 

          [code:1:ff78191c7b]#include <stdlib.h>
          #include <stdio.h>
          #include "memwatch.h"

          int main(void)
          {
          char *ptr1;
          char *ptr2;

          ptr1 = malloc(512);
          ptr2 = malloc(512);

          ptr2 = ptr1;
          free(ptr2);
          free(ptr1);
          }[/code:1:ff78191c7b]
          清單 1 中的代碼將分配兩個 512 字節(jié)的內(nèi)存塊,然后指向第一個內(nèi)存塊的指針被設(shè)定為指向第二個內(nèi)存塊。結(jié)果,第二個內(nèi)存塊的地址丟失,從而產(chǎn)生了內(nèi)存泄漏。
          現(xiàn)在我們編譯清單 1 的 memwatch.c。下面是一個 makefile 示例:
          test1 

          [code:1:ff78191c7b]gcc -DMEMWATCH -DMW_STDIO test1.c memwatch c -o test1[/code:1:ff78191c7b]
          當(dāng)您運(yùn)行 test1 程序后,它會生成一個關(guān)于泄漏的內(nèi)存的報(bào)告。清單 2 展示了示例 memwatch.log 輸出文件。
          清單 2. test1 memwatch.log 文件 

          [code:1:ff78191c7b]MEMWATCH 2.67 Copyright (C) 1992-1999 Johan Lindh

          ...
          double-free: <4> test1.c(15), 0x80517b4 was freed from test1.c(14)
          ...
          unfreed: <2> test1.c(11), 512 bytes at 0x80519e4
          {FE FE FE FE FE FE FE FE FE FE FE FE ..............}

          Memory usage statistics (global):
          N)umber of allocations made: 2
          L)argest memory usage : 1024
          T)otal of all alloc() calls: 1024
          U)nfreed bytes totals : 512[/code:1:ff78191c7b]
          MEMWATCH 為您顯示真正導(dǎo)致問題的行。如果您釋放一個已經(jīng)釋放過的指針,它會告訴您。對于沒有釋放的內(nèi)存也一樣。日志結(jié)尾部分顯示統(tǒng)計(jì)信息,包括泄漏了多少內(nèi)存,使用了多少內(nèi)存,以及總共分配了多少內(nèi)存。
          [color=blue:ff78191c7b]YAMD[/color:ff78191c7b]
          YAMD 軟件包由 Nate Eldredge 編寫,可以查找 C 和 C++ 中動態(tài)的、與內(nèi)存分配有關(guān)的問題。在撰寫本文時,YAMD 的最新版本為 0.32。請下載 yamd-0.32.tar.gz(請參閱參考資料)。執(zhí)行 make 命令來構(gòu)建程序;然后執(zhí)行 make install 命令安裝程序并設(shè)置工具。 {{分頁}}
          一旦您下載了 YAMD 之后,請?jiān)?nbsp;test1.c 上使用它。請刪除 #include memwatch.h 并對 makefile 進(jìn)行如下小小的修改:
          使用 YAMD 的 test1 

          gcc -g test1.c -o test1
          清單 3 展示了來自 test1 上的 YAMD 的輸出。
          清單 3. 使用 YAMD 的 test1 輸出 

          [code:1:ff78191c7b]YAMD version 0.32
          Executable: /usr/src/test/yamd-0.32/test1
          ...
          INFO: Normal allocation of this block
          Address 0x40025e00, size 512
          ...
          INFO: Normal allocation of this block
          Address 0x40028e00, size 512
          ...
          INFO: Normal deallocation of this block
          Address 0x40025e00, size 512
          ...
          ERROR: Multiple freeing At
          free of pointer already freed
          Address 0x40025e00, size 512
          ...
          WARNING: Memory leak
          Address 0x40028e00, size 512
          WARNING: Total memory leaks:
          1 unfreed allocations totaling 512 bytes

          *** Finished at Tue ... 10:07:15 2002
          Allocated a grand total of 1024 bytes 2 allocations
          Average of 512 bytes per allocation
          Max bytes allocated at one time: 1024
          24 K alloced internally / 12 K mapped now / 8 K max
          Virtual program size is 1416 K
          End.[/code:1:ff78191c7b]
          YAMD 顯示我們已經(jīng)釋放了內(nèi)存,而且存在內(nèi)存泄漏。讓我們在清單 4 中另一個樣本程序上試試 YAMD。
          清單 4. 內(nèi)存代碼(test2.c) 

          [code:1:ff78191c7b]#include <stdlib.h>
          #include <stdio.h>

          int main(void)
          {
          char *ptr1;
          char *ptr2;
          char *chptr;
          int i = 1;
          ptr1 = malloc(512);
          ptr2 = malloc(512);
          chptr = (char *)malloc(512);
          for (i; i <= 512; i++) {
          chptr[i] = 'S';
          }
          ptr2 = ptr1;
          free(ptr2);
          free(ptr1);
          free(chptr);
          }[/code:1:ff78191c7b]
          您可以使用下面的命令來啟動 YAMD:
          [code:1:ff78191c7b]./run-yamd /usr/src/test/test2/test2 [/code:1:ff78191c7b]
          清單 5 顯示了在樣本程序 test2 上使用 YAMD 得到的輸出。YAMD 告訴我們在 for 循環(huán)中有“越界(out-of-bounds)”的情況。
          清單 5. 使用 YAMD 的 test2 輸出 

          [code:1:ff78191c7b]Running /usr/src/test/test2/test2
          Temp output to /tmp/yamd-out.1243
          *********
          ./run-yamd: line 101: 1248 Segmentation fault (core dumped)
          YAMD version 0.32
          Starting run: /usr/src/test/test2/test2
          Executable: /usr/src/test/test2/test2
          Virtual program size is 1380 K
          ...
          INFO: Normal allocation of this block
          Address 0x40025e00, size 512
          ...
          INFO: Normal allocation of this block
          Address 0x40028e00, size 512
          ...
          INFO: Normal allocation of this block
          Address 0x4002be00, size 512
          ERROR: Crash
          ...
          Tried to write address 0x4002c000
          Seems to be part of this block:
          Address 0x4002be00, size 512
          ...
          Address in question is at offset 512 (out of bounds)
          Will dump core after checking heap.
          Done.[/code:1:ff78191c7b]
          MEMWATCH 和 YAMD 都是很有用的調(diào)試工具,它們的使用方法有所不同。對于 MEMWATCH,您需要添加包含文件 memwatch.h 并打開兩個編譯時間標(biāo)記。對于鏈接(link)語句,YAMD 只需要 -g 選項(xiàng)。 {{分頁}}
          [color=blue:ff78191c7b]Electric Fence[/color:ff78191c7b]
          多數(shù) Linux 分發(fā)版包含一個 Electric Fence 包,不過您也可以選擇下載它。Electric Fence 是一個由 Bruce Perens 編寫的 malloc() 調(diào)試庫。它就在您分配內(nèi)存后分配受保護(hù)的內(nèi)存。如果存在 fencepost 錯誤(超過數(shù)組末尾運(yùn)行),程序就會產(chǎn)生保護(hù)錯誤,并立即結(jié)束。通過結(jié)合 Electric Fence 和 gdb,您可以精確地跟蹤到哪一行試圖訪問受保護(hù)內(nèi)存。 Electric Fence 的另一個功能就是能夠檢測內(nèi)存泄漏。

          zhchhui 回復(fù)于:2003-09-15 10:49:18
          [b:95b8e28830] [size=18:95b8e28830]第 2 種情況:使用 strace[/size:95b8e28830][/b:95b8e28830]
          strace 命令是一種強(qiáng)大的工具,它能夠顯示所有由用戶空間程序發(fā)出的系統(tǒng)調(diào)用。strace 顯示這些調(diào)用的參數(shù)并返回符號形式的值。 strace 從內(nèi)核接收信息,而且不需要以任何特殊的方式來構(gòu)建內(nèi)核。將跟蹤信息發(fā)送到應(yīng)用程序及內(nèi)核開發(fā)者都很有用。在清單 6 中,分區(qū)的一種格式有錯誤,清單顯示了 strace 的開頭部分,內(nèi)容是關(guān)于調(diào)出創(chuàng)建文件系統(tǒng)操作(mkfs)的。strace 確定哪個調(diào)用導(dǎo)致問題出現(xiàn)。
          清單 6. mkfs 上 strace 的開頭部分 

          [code:1:95b8e28830]execve("/sbin/mkfs.jfs", ["mkfs.jfs", "-f", "/dev/test1"], &
          ...
          open("/dev/test1", O_RDWR|O_LARGEFILE) = 4
          stat64("/dev/test1", {st_mode=&, st_rdev=makedev(63, 255), ...}) = 0
          ioctl(4, 0x40041271, 0xbfffe128) = -1 EINVAL (Invalid argument)
          write(2, "mkfs.jfs: warning - cannot setb" ..., 98mkfs.jfs: warning -
          cannot set blocksize on block device /dev/test1: Invalid argument )
          = 98
          stat64("/dev/test1", {st_mode=&, st_rdev=makedev(63, 255), ...}) = 0
          open("/dev/test1", O_RDONLY|O_LARGEFILE) = 5
          ioctl(5, 0x80041272, 0xbfffe124) = -1 EINVAL (Invalid argument)
          write(2, "mkfs.jfs: can't determine device"..., ..._exit(1)
          = ?[/code:1:95b8e28830]
          清單 6 顯示 ioctl 調(diào)用導(dǎo)致用來格式化分區(qū)的 mkfs 程序失敗。ioctl BLKGETSIZE64 失敗。(BLKGET- SIZE64 在調(diào)用 ioctl 的源代碼中定義。) BLKGETSIZE64 ioctl 將被添加到 Linux 中所有的設(shè)備,而在這里,邏輯卷管理器還不支持它。因此,如果 BLKGETSIZE64 ioctl 調(diào)用失敗,mkfs 代碼將改為調(diào)用較早的 ioctl 調(diào)用;這使得 mkfs 適用于邏輯卷管理器。

          zhchhui 回復(fù)于:2003-09-15 10:57:11
          [b:627becdd94][size=18:627becdd94] 第 3 種情況:使用 gdb 和 Oops[/size:627becdd94][/b:627becdd94]
          您可以從命令行使用 gdb 程序(Free Software Foundation 的)來找出錯誤,也可以從諸如 Data Display Debugger(DDD)這樣的幾個圖形工具之一使用 gdb 程序來找出錯誤。您可以使用 gdb 來調(diào)試用戶空間程序或 Linux 內(nèi)核。這一部分只討論從命令行運(yùn)行 gdb 的情況。
          使用 gdb program name 命令啟動 gdb。gdb 將載入可執(zhí)行程序符號并顯示輸入提示符,讓您可以開始使用。您可以通過三種方式用 gdb 查看進(jìn)程:
          ?使用 attach 命令開始查看一個已經(jīng)運(yùn)行的進(jìn)程;attach 將停止進(jìn)程。
          ?使用 run 命令執(zhí)行程序并從頭開始調(diào)試程序。
          ?查看已有的核心文件來確定進(jìn)程終止時的狀態(tài)。要查看核心文件,請用下面的命令啟動 gdb。 
          gdb programname corefilename 
          要用核心文件進(jìn)行調(diào)試,您不僅需要程序的可執(zhí)行文件和源文件,還需要核心文件本身。要用核心文件啟動 gdb,請使用 -c 選項(xiàng): 
          gdb -c core programname 
          gdb 顯示哪行代碼導(dǎo)致程序發(fā)生核心轉(zhuǎn)儲。
          在運(yùn)行程序或連接到已經(jīng)運(yùn)行的程序之前,請列出您覺得有錯誤的源代碼,設(shè)置斷點(diǎn),然后開始調(diào)試程序。您可以使用 help 命令查看全面的 gdb 在線幫助和詳細(xì)的教程。
          [color=blue:627becdd94]kgdb[/color:627becdd94]
          kgdb 程序(使用 gdb 的遠(yuǎn)程主機(jī) Linux 內(nèi)核)提供了一種使用 gdb 調(diào)試 Linux 內(nèi)核的機(jī)制。kgdb 程序是內(nèi)核的擴(kuò)展,它讓您能夠在遠(yuǎn)程主機(jī)上運(yùn)行 gdb 時連接到運(yùn)行用 kgdb 擴(kuò)展的內(nèi)核機(jī)器。您可以接著深入到內(nèi)核中、設(shè)置斷點(diǎn)、檢查數(shù)據(jù)并進(jìn)行其它操作(類似于您在應(yīng)用程序上使用 gdb 的方式)。這個補(bǔ)丁的主要特點(diǎn)之一就是運(yùn)行 gdb 的主機(jī)在引導(dǎo)過程中連接到目標(biāo)機(jī)器(運(yùn)行要被調(diào)試的內(nèi)核)。這讓您能夠盡早開始調(diào)試。請注意,補(bǔ)丁為 Linux 內(nèi)核添加了功能,所以 gdb 可以用來調(diào)試 Linux 內(nèi)核。
          使用 kgdb 需要兩臺機(jī)器:一臺是開發(fā)機(jī)器,另一臺是測試機(jī)器。一條串行線(空調(diào)制解調(diào)器電纜)將通過機(jī)器的串口連接它們。您希望調(diào)試的內(nèi)核在測試機(jī)器上運(yùn)行;gdb 在開發(fā)機(jī)器上運(yùn)行。gdb 使用串行線與您要調(diào)試的內(nèi)核通信。


          評論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉