Linux下的調試工具

Linux下的調試工具linux

 隨着XP的流行,人們愈來愈注重軟件的前期設計、後期的實現,以及貫穿於其中的測試工做,通過這個過程出來的天然是高質量的軟件。甚至有人聲稱XP會淘汰調試器!這固然是有必定道理的,然而就目前的現實來看,這仍是一種理想。在平常工做中,調試工具仍是必不可少的。在Linux下,調試工具並不是只有gdb,還有不少其它調試工具,它們都各有所長,側重方面也有所不一樣。本文介紹幾種筆者經常使用的調試工具: c++


  •  1. mtrace


在linux下開發應用程序,用C/C++語言的居多。內存泄露和內存越界等內存錯誤,無疑是其中最頭疼的問題之一。glibc爲解決內存錯誤提供了兩種方案: 編程

 一種是hook內存管理函數。hook內存管理函數後,你能夠經過記下內存分配的歷史記錄,在程序終止時查看是否有內存泄露,這樣就能夠找出內存泄露的地方了。你也能夠經過在所分配內存的首尾寫入特殊的標誌,在釋放內存時檢查該標誌是否被破壞了,這樣就能夠達到檢查內存越界問題的目的。 小程序

 另一種方法更簡單,glibc已經爲第一種方案提供了默認的實現,你要作的只是在特定的位置調用mtrace/muntrace兩個函數,它們的函數原型以下: 函數

       #include <mcheck.h> 工具

       void mtrace(void); 性能

void muntrace(void); 單元測試

你可能會問,在哪裏調這兩種函數最好?這沒有固定的答案,要視具體狀況而定。對於小程序來講,在進入main時調用mtrace,在退出main函數時調用muntrace。對於大型軟件,這樣作可能會記錄過多的信息,分析這些記錄會比較慢,這時能夠在你所懷疑代碼的兩端調用。 測試

 另外,還須要設置一個環境變量MALLOC_TRACE,它是一個文件名,要保證當前用戶有權限建立和寫入該文件。glibc的內存管理器會把內存分配的歷史信息寫入到MALLOC_TRACE指定的文件中。 this

程序運行完畢後,使用mtrace工具分析這些內存分配歷史信息,能夠查出內存錯誤的位置(mtrace在glibc-utils軟件包裏)


  •  2. strace


在編程時,檢查函數的返回值是一種好習慣。對於像glibc等標準C的函數,光檢查返回值是不夠的,還須要檢查errno的值。這樣的程序每每顯得冗長,不夠簡潔。同時也多是出於偷懶的緣由,大多數程序裏並無作這樣的檢查。

 這樣的程序,一旦出現錯誤,用調試器一步一步定位錯誤,而後想法查出錯誤的緣由,也是能夠的,不過比較麻煩,對調試器來講有些大材小用,不太可取。這時,用strace命令可能會更方便一點。它能夠顯示各個系統調用/信號的執行過程和結果。好比文件打開出錯,一眼就看出來了,連錯誤的緣由(errno)都知道。


  •  3. binutil


binutil是一系列的工具,你可能根本不知道它們的存在,可是沒有它們你卻步履維艱。Binutil包括下列工具:

  • ld - the GNU linker.
  • as - the GNU assembler.
  • addr2line - Converts addresses into filenames and line numbers.
  • ar - A utility for creating, modifying and extracting from archives.
  • c++filt - Filter to demangle encoded C++ symbols.
  • gprof - Displays profiling information.
  • nlmconv - Converts object code into an NLM.
  • nm - Lists symbols from object files.
  • objcopy - Copys and translates object files.
  • objdump - Displays information from object files.
  • ranlib - Generates an index to the contents of an archive.
  • readelf - Displays information from any ELF format object file.
  • size - Lists the section sizes of an object or archive file.
  • strings - Lists printable strings from files.
  • strip - Discards symbols.
  • windres - A compiler for Windows resource files.

其中部分工具對調試極有幫助,如:

你能夠用objdump反彙編,查看目標文件或可執行文件內部信息。

你能夠用addr2line把機器地址轉換到代碼對應的位置。

你能夠用nm查看目標文件或可執行文件中的各類符號。

你能夠用gprof分析各個函數的使用狀況,找出性能的瓶頸所在(這須要加編譯選項)


  •  4. ld-linux


如今加載ELF可執行文件的工做,已經落到ld-linux.so.2頭上了。你可能會問,這與有調試程序有關係嗎?有的。好比,在linux中,共享庫裏全部非static的函數/全局變量都是export的,更糟的是C語言中沒有名字空間這個概念,致使函數名極易衝突。在多個共享庫中,名字衝突引發的BUG是比較難查的。這時,你能夠經過設置LD_ DEBUG環境變量,來觀察ld-linux.so加載可執行文件的過程,從中能夠獲得很多幫助信息。LD_ DEBUG的取值以下:

  • libs        display library search paths
  • reloc       display relocation processing
  • files       display progress for input file
  • symbols     display symbol table processing
  • bindings    display information about symbol binding
  • versions    display version dependencies
  • all         all previous options combined
  • statistics  display relocation statistics
  • unused      determined unused DSOs
  • help        display this help message and exit

  • 5. gdb

對於真正意義的調試器來講,gdb在linux下是獨一無二的。它有多種包裝,有字符界面的,也有圖形界面的,有單獨運行的,也有集成到IDE中的。gdb功能強大,圖形界面的gdb容易上手一點,但功能無疑受到了一些限制,相信大部分高手仍是願意使用字符界面的。Gdb太經常使用了,這裏再也不多說。

 

  •  6. gcc/boundschecker

相信不少人用過win32下的BoundsChecker(Compuware公司)和Purify(IBM公司)兩個工具吧。它們的功能實在太強大了,絕非能經過重載內存管理函數就能夠作到,它們在編譯時插入了本身的調試代碼。

 gcc也有個擴展,經過在編譯時插入調試代碼,來實現更強大的檢查功能。固然這要求從新編譯gcc,你能夠到http://sourceforge.net/projects/boundschecking/ 下載gcc的補丁。它的可移植性很是好,筆者曾一個ARM 平臺項目裏使用過,效果不錯。

 

  •  7. valgrind

最好的東西每每最後才見到。Valgrind是個人最愛,用習慣了,寫的程序不在valgrind下跑一遍,就像沒有寫單元測試程序同樣,有點放心不下。它有BoundsChecker/Purify的功能,並且速度更快。有點遺憾的是valgrind目前只支持x86平臺,固然,這對大多數狀況已經足夠了。
你能夠到http://valgrind.org/ 下載最新版本。

 

valgrind應該學會使用一下!

 

轉載於http://my.oschina.net/mavericsoung/blog/145227

相關文章
相關標籤/搜索