Linux下的除錯工具
Linux下的除錯工具
隨著XP的流行,人們越來越注重軟體的前期設計、後期的實現,以及貫穿於其中的測試工作,經過這個過程出來的自然是高質量的軟體。甚至有人聲稱XP會淘汰偵錯程式!這當然是有一定道理的,然而就目前的現實來看,這還是一種理想。在日常工作中,除錯工具還是必不可少的。在Linux下,除錯工具並非只有gdb,還有很多其它除錯工具,它們都各有所長,側重方面也有所不同。本文介紹幾種筆者常用的除錯工具:
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指定的檔案中。
程式執行完畢後,使用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/ 下載最新版本。
相關文章
- 【linux學習--工具篇】串列埠除錯工具Linux串列埠除錯
- Linux 黑乎乎的命令列下,如何除錯 Python?Linux命令列除錯Python
- Linux除錯Linux除錯
- Linux下搭建FFmpeg開發除錯環境Linux除錯
- Linux環境下C++除錯的三板斧LinuxC++除錯
- Android除錯工具Genymotion的使用Android除錯
- (14)caffe總結之Linux下Caffe如何除錯Linux除錯
- 【開源】基於.net6+gtksharp實現的Linux下的圖形介面串列埠除錯工具Linux串列埠除錯
- vscode 除錯linux程式VSCode除錯Linux
- Homestead 下關於 PhpStorm Xdebug 斷點除錯工具的安裝PHPORM斷點除錯
- Linux除錯檢視搜尋工具集-緩慢增加中Linux除錯
- 前端必須知道的除錯工具前端除錯
- 嵌入式Linux的除錯方案Linux除錯
- Windows 除錯工具課程Windows除錯
- react19.0.0 除錯工具React除錯
- Linux核心使用gdb除錯Linux除錯
- Laravel 一個簡單的除錯工具Laravel除錯
- LLDebugTool – 便捷的IOS除錯工具(Version 1.1.5)iOS除錯
- LLDebugTool - 便捷的IOS除錯工具(支援Swift)iOS除錯Swift
- LLDebugTool - 便捷的IOS除錯工具(Version 1.1.3)iOS除錯
- LLDebugTool - 便捷的IOS除錯工具(Version 1.1.5)iOS除錯
- Luna:你想要的 React Native 除錯工具React Native除錯
- 【cypress】4. 豐富的除錯工具除錯
- Linux MIPI 除錯中常見的問題Linux除錯
- 虛擬串列埠工具和串列埠除錯工具詳解 - 附下載地址串列埠除錯
- [翻譯] 除錯 Rxjs(一):工具除錯JS
- serial for mac 串列埠除錯工具Mac串列埠除錯
- Node 除錯工具入門教程除錯
- Linux中使用GDB除錯程式Linux除錯
- linux串列埠命令列除錯Linux串列埠命令列除錯
- Windows 下如何除錯 PowerShellWindows除錯
- Laravel Telescope:優雅的應用除錯工具Laravel除錯
- 超好用的VueJs除錯工具——vue-devtoolsVueJS除錯dev
- LLDebugTool - 便捷的IOS除錯工具(支援元件化)iOS除錯元件化
- MacOS 下的 Laravel 除錯軟體 - TinkerwellMacLaravel除錯
- 在WIN下刪除LINUXLinux
- 2019最新Python學習教程升級版(Linux 下如何除錯 Python?)PythonLinux除錯
- ESP8266-01-除錯工具(AT指令)除錯