GDB入門教程之如何使用GDB啟動調試

2021-02-13 女程式設計師說

寫在前面:今天開始嘗試寫寫除Vim外的其他內容,仍然是以技術為主,可能涉及的內容包括Linux、正則表達式、gdb、makefile等內容,不知道小夥伴們有沒有興趣看呢?不管如何,也算是我自己的知識沉澱吧~ 我把公眾號改名了,你們猜猜新名字是啥?


GDB (The GNU Project Debugger)是 Linux 系統下調試 C 和 C++ 程序的主要神兵。本文介紹多種方式下使用 GDB 啟動進程調試的方法和命令。

要使得 C 和 C++ 程序能在 GDB 下正常進行調試,必須在程序編譯期間把基本的調試信息(如變量名、函數名、函數調用堆棧等)添加到可執行文件中。gcc、cc、g++等編譯器可通過編譯參數 -g 指定添加調試信息。

當使用GDB加載不包含調試信息的二進位文件或進程時,GDB終端會提示錯誤信息:"no debugging symbols found"。

對於本地的某個二進位文件 demo ( GDB 也支持遠程調試),若其啟動時不需要命令行參數,則可以在shell下使用命令 gdb demo 進入 GDB,並輸入 run (縮寫形式 r) 啟動對demo的調試。

若 demo 程序啟動時需要命令行參數,則可以在使用 gdb demo 命令進入GDB後,使用命令 run arg1 arg2... 提供命令行參數並啟動對demo程序的調試。

使用GDB調試正在運行的程序時,必須先找到該程序運行在作業系統中的進程號 (PID)。可以使用 Linux 命令 ps-ef|grep-w demo 、 ps-aux|grep-w demo 或 pidof demo 獲取到 demo 進程當前的進程號。

獲取到待調試的目標進程號後 (假設為 pid ),可以使用 gdb 命令進入 GDB 終端,並使用 attach pid 的方式啟動對當前正在運行的 demo 進程的 GDB 調試。

也可以使用 gdb-p pid 命令直接進入 GDB 並啟動對該進程的調試。

對於使用多線程模式的進程,可以在 GDB 中使用 info threads 命令顯示當前進程中所有線程的基本調試信息,包括:GDB 分配的線程ID、線程堆棧等。線程列表中,GDB 線程 ID 左側的 * 表示當前真正被調試的線程。

可通過 thread tid 命令切換和啟動對 GDB 線程號為 tid 的線程進行調試。關於使用 GDB 調試多進程和多線程,後續會有獨立的文章進行詳細介紹。

當程序在 Linux 系統下發生異常崩潰(如段錯誤)時,內核會將該應用程式在崩潰發生時的內存數據、程序調用堆棧等核心信息轉存到磁碟,這種功能稱之為 core dump,中文可翻譯為 核心轉儲

core dump 是程序異常退出時的內存快照,是異常發生後對程序進行現場還原和故障排查的關鍵線索。Linux 進程 core 掉可以說是所有 C 和 C++ 程式設計師接觸最頻繁而又最不想碰到的問題。

可通過 ulimit-c 查看和指定 core 文件的大小,通過修改 /proc/sys/kernel/core_pattern 文件可指定 core 文件保存在本地磁碟中的路徑和文件名格式。

GDB 對 core 文件的分析和調試提供了非常強大的功能支持,可使用 gdb demo/data/core/xxx 啟動對 demo 進程某次產生的core文件 /data/core/xxx 的分析和調試,也可以使用

gdb-c/data/core/xxx 加載和分析 core 文件。

GDB 正常加載 core 文件後,便可以使用 backtrace (縮寫形式 bt) 顯示程序異常退出時刻的函數堆棧情況,再使用 frame、 print、 up、 down、 where 等命令對異常現場進行詳細分析。

為了讓程序產生 dump ,將 demo.cpp 中的輸出語句 printf("%s: %d\n",(char*)ptr,array[i]); 改成 printf("%s: %s\n",(char*)ptr,array[i]); 後在編譯時加入 -w 參數忽略掉警告後重新生成 demo 可執行文件。

關於 GDB 調試程序和 core 文件的具體方法和命令,請關注公眾號 GDB 系列的後續文章。

PS:使用 quit (縮寫形式 q) 可退出 GDB。

相關焦點

  • GDB簡明教程:快速入門
    本教程將會帶領大家熟悉和掌握程序調試常用的GDB命令,讓我們的開發工作更加高效。需要調試的可執行程序a.out生成以後,接下來就可以使用gdb進行調試了,可以使用下面的命令來進入GDB調試環境,調試a.out(編譯生成的a.out文件位於/home/gdb目錄下):
  • 原來gdb的底層調試原理這麼簡單
    相信每位嵌入式開發工程師都使用過 gdb 來調試程序,如果你說沒有用過,那只能說明你的開發經歷還不夠坎坷,還需要繼續被 BUG 吊打。我們都知道,在使用 GCC 編譯時,可以增加 -g 選項在可執行文件中嵌入更多的調試信息,那麼具體嵌入了哪些調試信息呢?這些調試信息是如何與二進位的指令之間進行相互交互的呢?
  • GDB調試實戰二啟動調試
    int len = pData_->GetMemCount(0);(gdb) 通過c命令來啟動進程的運行。二、線程切換控制在前面看到了線程的切換,下面使用命令鎖定一個線程來監控:(gdb) show scheduler-lockingMode for locking scheduler during execution is "step".
  • GDB調試還不會?看這篇就夠了!
    總覽本文為GDB調試指南,參考GDB調試手冊,但加入了很多實例,目前已有的篇目:在Linux使用C/C++進行開發,不了解gdb的基本使用,是有點說不過去的,網上也有官方的GDB教程,或者其他教程,本文是藉助實例,介紹了如何使用GDB進行調試。看完這篇,GDB的日常使用就夠了。
  • 用圖文帶你徹底弄懂GDB調試原理
    相信每位嵌入式開發工程師都使用過gdb來調試程序,如果你說沒有用過,那只能說明你的開發經歷還不夠坎坷,還需要繼續被 BUG吊打。我們都知道,在使用gcc編譯時,可以使用-g選項在可執行文件中嵌入更多的調試信息,那麼具體嵌入了哪些調試信息?這些調試信息是如何與二進位的指令之間進行相互交互?
  • 你還在用GDB調試程序嗎?
    本文主要講述如何使用Python來提高你的GDB調試技能, 讓你從繁重的重複的工作裡面掙脫出來呼吸新鮮空氣。首先,第一件事,使用gdb7.x以上的版本,最好9.x的。因為Python的支持是從gdb7.0(2009年?)開始的。
  • GDB調試實戰三完整的數據流程
    一、基本流程介紹經過了前面的各種準備,再結合學習過的GDB的各種調試方法和技巧,下面進行一次完整的數據調試流程。整個程序的流程基本是模擬網絡和網口通信,區別在於完整包的大小不同,網口是100個字節而串口是60個字節。程序在啟動時,啟動了兩個線程,生產者直接從一個固定的字符串數組取大小不同的數組來送到數據處理的兩個std::vector 中。
  • Linux C/C++ 開發人員要熟練掌握 GDB 調試代碼塊
    一、啟動GDB調試使用 GDB 調試程序一般有三種方式: gdb filename gdb attach pid gdb filename corename1、直接調試目標程序2、附加進程3、調試 core
  • GDB 調試 .NET 程序實錄 - .NET 調用 .so 出現問題怎麼解決
    GC.EndNoGCRegion();工具調試經過提示,知道可以使用 GDB 調試 .so,於是馬上 Google 查找資料,經過一段時間後,學會了使用這些工具查詢異常堆棧信息。GDBGNU Debugger,也稱為 gdb,是用於 UNIX系統調試 C 和 C ++ 程序的最流行的調試器。
  • 常用 GDB 命令中文速覽
    run — 啟動被調試的程序,縮寫為 rbacktrace — 查看程序調用棧的信息,縮寫為 btptype — 列印類型 TYPE 的定義break使用 break 命令(縮寫 b)來設置斷點。警告:如果當控制在沒有調試信息的情況下編譯的函數中使用 step 命令,則執行將繼續進行,直到控制到達具有調試信息的函數。 同樣,它不會進入沒有調試信息編譯的函數。要執行沒有調試信息的函數,請使用 stepi 命令,詳見後文。reverse-step反向單步執行程序,直到到達另一個源碼行的開頭。
  • 使用gdb+python查看C/C++進程內存分配情況
    內存使用和管理在C/C++程序中是一個無法繞開的問題, 在gdb支持python script以後, 我們就可以使用gdb這個新的特性來幫助我們查看在glibc ptmalloc算法中管理的內存的情況。為了方便, 下面我們主要針對x64環境。在可以查看內存分配情況以前, 我們當然需要知道ptmalloc算法大致是一個什麼樣子的。
  • gdb 提示 coredump 文件 truncated 問題排查
    本文以線上問題為例,藉助這個Case我們深入了解一下這類問題的排查思路,以及如何使用一些調試工具、閱讀內核原始碼,更清晰地了解coredump的處理過程。希望能為大家在排查這類問題的時候,提供一個清晰的脈絡。
  • GDB入門教程之查看變量
    在學會了使用 GDB 啟動調試和設置調試斷點後,為了驗證程序的執行結果是否符合預期,經常需要查看和驗證一些關鍵變量的值。
  • 如何調試多線程程序
    在上一篇文章《使用 gdb 調試多進程程序 —— 以調試 nginx 為例》我們介紹了如何使用 gdb 調試多進程程序,這篇文章我們來介紹下如何使用 gdb 調試多線程程序,同時這個方法也是我閱讀和分析一個新的 C/C++ 項目常用的方法。當然,多線程調試的前提是你需要熟悉多線程的基礎知識,包括線程的創建和退出、線程之間的各種同步原語等。
  • GDB入門教程之恢復程序執行
    拖了好久了,今天繼續之前的 GDB
  • dlua 0.1 發布,gdb 風格的 lua 調試器
    dlua 是一個類似 gdb 的 lua 調試器。
  • Go 快速入門篇(三):單元測試、問題定位及代碼調試
    GDB 調試日常開發使用 GoLand 自帶的代碼調試功能就夠了,如果你想要通過更加 Hacker 的方式調試代碼,可以選擇 GDB。GDB 是一個由 GNU 開源組織發布的、Unix/Linux 作業系統下的、基於命令行的、功能強大的程序調試工具,Go 語言編譯後的二進位文件支持通過 GDB 進行調試,比如上篇教程通過 go build calc 編譯出來的可執行文件 calc,就可以直接用以下命令以調試模式運行:gdb calc
  • Linux 系統內核的調試
    本文將首先介紹 Linux 內核上的一些內核代碼監視和錯誤跟蹤技術,這些調試和跟蹤方法因所要求的使用環境和使用方法而各有不同,然後重點介紹三種 Linux 內核的原始碼級的調試方法。  調試是軟體開發過程中一個必不可少的環節,在 Linux 內核開發的過程中也不可避免地會面對如何調試內核的問題。
  • 在VIM中實現對嵌入式軟體的調試
    其強大的gdb調試工具可以方便地對嵌入式平臺上的程序進行跟蹤調試;而Linux下強悍的VIM編輯器,不僅可以方便地調用make文件對代碼進行編譯,而且通過腳本的配置還可輕鬆地成為高效的代碼編輯環境。流傳著這樣一種說法,「世界上的程式設計師分三種,一種使用Emacs,一種使用VIM,剩餘的是其他。」
  • Android動態調試-不用IDA Pro
    為什麼不用gdb,因為lldb的出現,取代gdb只是遲早的事情,可以說gdb是Depracated。在 Android逆向之ARM64靜態分析對app的中的so進行了靜態分析,這篇文章介紹兩種動態調試的方式,一種是radare2,另一種是lldb。