1. 程式人生 > >Linux 程式設計師的自我修養:玩轉 GDB 除錯

Linux 程式設計師的自我修養:玩轉 GDB 除錯

我從學生時代到進入軟體開發這個行業,不知不覺已經十餘年了。這些年,先後在網遊公司做過遊戲伺服器,為上海某交易所做過金融交易系統、在金融證券公司做過股票證券交易系統和即時通訊軟體、在音視訊直播公司做過直播伺服器,各種專案使用的伺服器作業系統都是 Linux,開發語言是 C/C++。

正如從事 Windows C/C++ 開發的一定要熟悉 Visual Studio、從事 Java 開發的要熟悉 Eclipse 或 IntelliJ IDEA、從事 Android 開發的要熟悉 Android Studio、從事 iOS 開發的要熟悉 XCode 一樣,從事 Linux 開發的要熟悉 GDB

GDB 有多重要?分享我的經歷側面回答一下這個問題。

1. 熟練使用 GDB 是 Linux C/C++ 開發人員的基本素養

我之前有份後臺開發的工作,部門有個不成文的規定:即使很明確的程式,每個分支必須使用 GDB 偵錯程式去追蹤一下程式,看看執行過程中的各種中間狀態是否符合預期。

很多人想當然地覺得程式碼就會按預期的流程去執行,但是實際上一到生產環境總會出現這樣那樣的問題,這是很多 Bug 產生的原因。在除錯的過程中,能夠學到很多可能想不到的知識。

我開始是做 Windows C/C++ 開發的,後來轉做 Linux C/C++ 開發,剛開始對 Linux 環境下沒有圖形化的視覺化介面很不習慣,因此很多簡單的程式碼段也就不願意去除錯,後來系統事故頻發,造成了一些不好的影響,慢慢地意識到除錯的重要性。

後來,我做了技術管理者,每次面試技術候選人,我會問他熟悉哪些開發工具。有些面試者對各種開發工具都不熟悉,我猜想這類應聘者應該是基本“不寫程式碼”或者“不會寫程式碼”的,面試結果可想而知。

“工欲善其事、必先利其器”,作為一名合格的軟體開發者,至少得熟悉一種軟體開發工具和偵錯程式,而對於 Linux C/C++ 後臺開發,舍 GDB 其誰?

雖然 Linux 系統下大家編寫 C/C++ 程式碼的 IDE 可以自由選擇,但是除錯生成的 C/C++ 程式一定是直接或者間接使用 GDB。

可以毫不誇張地說,我做的所有專案的開發和除錯包括故障排查都是利用 GDB 完成的。除錯是開發流程中一個非常重要的環節,對於從事 Linux C/C++ 的開發人員,熟練使用 GDB 除錯是一項基本要求

2 熟練使用 GDB 是學習優秀開源專案的一把鑰匙

一些初中級開發者可能想通過閱讀一些優秀的開源專案來提高自己的編碼水平,但是隻閱讀程式碼,不容易找到要點,或者會誤解程式的執行邏輯,最終迷失方向。

如果能實際利用偵錯程式去把某個開源專案除錯一遍,學習效果才能更好。站在 Linux C/C++ 後臺開發的角度來說,學會了 GDB 除錯,就可以對各種 C/C++ 開源專案(如 Redis、Apache、Nginx 等)遊刃有餘

簡而言之,GDB 除錯是學習這些優秀開源專案的一把鑰匙。

另外,由於 C++ 這門語言多型特性的存在,我們看到的程式碼執行脈絡和實際中的執行流程可能會不一樣,特別容易搞錯。

我覺得最好的學習方法就是除錯這些開源軟體,無論多麼複雜的程式,只要可以除錯,就總可以搞得明明白白的。而一些程式的細節,我們可以通過修改原始碼除錯觀察,最終把原理搞得透徹。

3 我的 GDB 學習軌跡

剛開始,我通過網路資料學會了一些簡單的 GDB 命令,這時候我在工作中會刻意找一些 demo 程式去除錯。

在除錯的過程中,遇到了一些需要重複操作才能觸發的斷點,在厭倦反覆手工操作以後,學會了臨時斷點、條件斷點和硬體斷點的新增方法。

後來在跟多執行緒程式鬥智鬥勇的過程中,學會了如何在各個執行緒之間切換和檢視當前執行緒呼叫堆疊

再後來學習 Apache HTTP Server、Nginx 這樣的軟體,新的連線會 fork 一個新的程序來處理客戶端資料,這又逼著我去研究利用 GDB 除錯多程序程式

當在 GDB 中由於字串太長或者遇到了 \0 的字元內容時,print 命令顯示字串不全,我不得不再次尋找答案。

當遇到 stl 容器中的元素是自定義元素時,GDB 自帶的 print 命令顯示效果可能不盡如人意,我又尋找按自己的要求顯示這些元素的方法。

辦法總比困難多,在堅持之後,我發現已經找到了能夠搞明白任何 Linux C/C++ 程式的鑰匙。

而這把鑰匙是很多人苦苦尋找的

我把找到這把鑰匙的經驗彙集成冊,在 GitChat 平臺上釋出了《Linux GDB 除錯指南》,希望能幫助需要的朋友找到自己的鑰匙。

這個圖文課程共 19 篇,內容由淺至深,詳細地講解了除錯的基本原理和實際專案除錯中各種 GDB 命令的靈活使用。

與網路中各種 GDB 除錯教程不同,它結合我這些年開發與除錯各種 C/C++ 專案的經驗,除了 GDB 各種基礎命令的講解,還專門介紹了一些高階 GDB 除錯技巧。尤其是多執行緒程式的除錯,這是令很多開發者頭疼的一個難題。

最後給出了一個完整的使用 GDB 來分析和學習 Redis 網路通訊模組的原始碼案例,希望以此拋磚引玉,幫助大家掌握學習開源軟體的方法。
在這裡插入圖片描述

當然,我們也建立了課程售後服務群,如果在課程學習的過程中有任何疑問或者困惑,可以加群互相溝通討論。

課程特色

  • 本課程不是人云亦云地介紹 GDB 的各個命令的用法,而是從 what、how、why 三個角度來介紹 GDB 除錯中的技巧和注意事項;所引用的示例也不是“helloworld”式的 demo,而是以時下最流行的記憶體資料庫 Redis 為示例物件。

  • 整個課程循序漸進,從基礎的除錯符號原理,到 GDB 啟動除錯的方式,再到常用命令詳解,接著介紹 GDB 高階除錯技巧和一些更強大的 GDB 擴充套件工具,最後使用 GDB 帶領讀者分析 Redis 伺服器端和客戶端的網路通訊模組。

  • 在這個課程中讀者不僅可以學習到實實在在的除錯技巧和網路程式設計知識,也可以學習到如何梳理開源軟體專案結構和原始碼分析思路。

在選擇哪個程式作為 GDB 除錯的教學程式時,著實讓我糾結了很久。很多 GDB 教程都是人為的“造”一些例項程式碼,我感覺這樣做有點脫離實際生產,實際專案中的程式碼與這種“造”出來的程式碼相差很大,同時程式很難調;

不過實際專案中的程式碼,由於企業單位的保密協議要求,也不方便外傳,因而拋棄了自己編寫的幾個例項程式碼,經過慎重考慮,本課最終選擇帶領讀者除錯 Redis 程式碼。

受眾人群

  • 希望學習 Linux C/C++ 開發和系統原理的讀者
  • 希望學習除錯知識和提高除錯能力的後臺 C/C++ 開發人員
  • 希望通過閱讀和除錯來學習開源 C/C++ 專案的讀者
  • 希望學習網路程式設計和了解 Redis 網路通訊模組設計思路的讀者
  • 希望學習如何整體把握一個開源 C/C++ 專案的原始碼的讀者
    在這裡插入圖片描述

作者簡介

范蠡,資深開發工程師,擔任過 C++ 客戶端和伺服器端開發主程,先後做過網際網路金融交易系統、即時通訊、遊戲伺服器、音視訊直播伺服器等專案,目前在某大型網際網路公司任開發經理一職。