深度解析Linux中的調試器gdb/cgdb的使用

Linux下我們編譯好的代碼,無法直接調試

gcc/g++默認的工作模式是realse模式

程序要調試的話,必須是debug模式,也就是說編譯的時候要加-g選項

gdb攜帶調試信息的exe

我們現在在文件夾里面創建一個文件lesson11

里面創建一個累加的代碼,從1到100

  1 #include <stdio.h>2 int Sum(int s,int e)3 {4   int result=0;5   int i=s;6   for(;i<=e;i++)                                                         7   {8     result+=i;9 10   }11   return result;12 }13 int main()14 {15   int start=1;16   int end=100;17   printf("I will begin\n");18   int n=Sum(start,end);19   printf("running done,resu;t is:[%d-%d]=%d\n",start,end,n);20   return 0;21 }

還有一個Makefile文件,主要是生成可調試的文件,使用-g選項進行操作

                                              ?? buffers 1 mycode:mycode.c2   gcc -o $@ $^ -g3 .PHONY:clean4 clean:5   rm -f mycode                                                           
~

如果我們想讓文件是debug模式可以進行調試的話,那么我們可以在后面加上-g的選項

在這里插入圖片描述
那么我們就可以對這個文件進行gdb調試操作了

如果我們要退出的話我們輸入這個quit就行了

在這里插入圖片描述

如果我們想顯示我們的源代碼的話我們可以直接輸入list就行了,簡寫成l就行了

在這里插入圖片描述
在這里插入圖片描述
但是我們想顯示我們的文件里面的內容的話

我們直接輸入命令l 1就行了,直接從第一行開始進行查看的操作

然后直接輸入回車的話就直接將所有的代碼都顯示出來的

在這里插入圖片描述
如果我們想在這個19行打上斷點的話,我們直接輸入b 19就行了在這里插入圖片描述
如果我們想讓程序直接跑完的話,我們直接輸入命令c就行了,程序就可以直接跑完了
在這里插入圖片描述

最后不想使用gdb了,我們直接輸入quit就能直接退出了

推薦一個cgdb,這個可以動態呈現我們的代碼

我們默認是沒有安裝的

我們可以輸入命令sudo yum install -y cgdb就行了

在這里插入圖片描述

我們進入到cgdb模式,上面是代碼,下面是我們的debug調試的操作

在這里插入圖片描述

我們可以輸入l mycode.c :1查看我們的mycode.c文件從我們的第一行開始進行查看操作
在這里插入圖片描述
我們的這里代碼片段左邊有個箭頭指向我們的16行

我們直接輸入run,簡化就是r然后就能直接運行結束
在這里插入圖片描述
所以我們運行r之前我們是需要提前將斷點打上去

斷點就是程序運行到某處停下來
我們使用b filename :line

b后面主要接的是行號

這個就是打斷點的操作了

我們這里打完斷點后,對應的行左邊的行號字體顏色都變成紅色了

在這里插入圖片描述
如果我們想要查看我們打的斷點的話

我們輸入命令info b就能進行斷點的查看操作了

在這里插入圖片描述
Num就是斷點的編號、

Type就是斷點的類型

Address就是我們將斷點達到哪個地址處

what就是描述我們打的是什么斷點,斷點的相關信息

我們只要打了斷點的話,我們運行run的話我們就直接在斷點處停下來了

如果我們要刪除斷點的話,我們是使用d進行斷點刪除的操作的

但是d后面不能是行號

只能是斷點的行號來進行刪除操作的

我們這里將編號為2的斷點進行刪除的操作,輸入d 2那么此時我們對應的2號斷點就刪除了

在這里插入圖片描述

總結:b 行號 創建斷點

     d 斷點編號   刪除對應的斷點info  b   查看所有的斷點的信息r  運行程序

我們如果不退出我們的cgdb的話,我們的斷點編號是依次進行線性遞增的

在這里插入圖片描述

我們之前在vs中的f10是逐過程,f11是逐語句

假設現在我們運行到了斷點的地方了,現在我們想直接跑完Sum函數

我們直接輸入next,簡單點就是n,我們可以逐過程進行操作

在這里插入圖片描述
在這里插入圖片描述
這個時候我們一直輸入命令n直到我們到了return 0那里,沒運行return 0

但是現在我們想進行重新進行調試,我們直接輸入r就行了

系統會詢問我們是否要重新進行調試

在這里插入圖片描述
那么我們又回到了我們一開始打斷點的地方了

我們現在想要運行我們下一行里面的函數了

我們可以輸入命令step簡化就是s

我們輸入s就能進入到函數內部了

這個就是逐語句了,那么我們這里19行直接進入到了Sum里面了

在這里插入圖片描述
我們如果想在gdb中逐語句的話,我們輸入了一個s,我們進到了函數內部

但是我們不想一直輸入s

我們可以輸入回車就行了

因為在gdb中我們的回車會記錄最近的一條指令

這個時候我們如果不想玩了,我們直接輸入r然后y就重新進入到了我們一開始的調試位置了

我們輸入命令cgdb mycode進行可執行程序的調整,而不是這個源文件

在這里插入圖片描述
下面我們就進入到了我們調試的頁面了在這里插入圖片描述
我們現在在第20行打斷點,輸入命令b 20在這里插入圖片描述
那么我們輸入info b可以查看我們剛剛打的斷點

斷點的本質其實是幫助我們在特定的位置處停下來,將代碼進行切塊,進行局部性追蹤

那么我們這里輸入了r之后我們的代碼就能在20行的位置停下來

在這里插入圖片描述
那么下面我們就可以逐語句(s)和逐過程(n)了

如果我們想進入到函數內的話逐語句,那么我們輸入s就行了

我們可以輸入命令bt進行函數棧幀的查看操作,可以查看調用棧

在這里插入圖片描述

現在的話我們是在函數內部了

但是我們想直接將函數結束掉,不想單步的移動了,我想讓這個函數跳轉到運行結束處

我們直接輸入命令finish就能跳出函數了

在這里插入圖片描述
那么我們結束了Sum函數,我們又回到了20行

那么就是說明現在系統進行的是將我們的Sum的返回值復制給n了

我們使用命令p n進行變量n打印的操作

我們發現呈現在我們面前的是一個隨機值,因為我們的n僅僅是開辟出來了

我們必須再往下面接著走一步

我們的n就讓寄存器放到內存里,那么我們的n就拿到了對應的結果了

我們給函數名打斷點就是給函數入口處打斷點

在這里插入圖片描述
在我們的vs中斷點是可以刪除和禁用的

那么就說明我們的斷點是可以進行打開和關閉的,我們的斷點是可以禁用的

現在我們不想刪除斷點,我們想將斷點使能掉給禁用

在這里插入圖片描述
默認我們的斷點的Enb=y

那么這一列就表示的是所有斷點是否被使能

我們現在要對17行的斷點進行使呢能的操作

那么我們輸入命令disable 4后面必須接的是我們的斷點的需要不是行號

然后我們就可以發現我們的4號斷點的Enb就變成了n了

在這里插入圖片描述
那么我們輸入命令r我們就知道到第5個斷點了

4號斷點雖然是存在的,但是已經被我們給忽略了,相當于是禁用的

如果我們想我們禁用掉的斷點重新起作用的話

我們可以輸入命令enable 4我們就可以讓我們禁用的4號斷點重新起作用了

調試的本質是什么 ?

1.找到問題

2.查看代碼上下文

我們這里有幾個斷點,一開始的話我們是從20號斷點開始的,我們輸入c,就是continue的意思

直接讓我們的程序從這個斷點運行到下一個斷點了

在這里插入圖片描述
那么我們這里因為我們的20-25這一塊的代碼沒出問題

所以我們的代碼并沒有出任何的問題

所以斷點的本質就是對我們的代碼進行塊級別劃分,以我們塊為單位快速定位出現問題的區域

finish可以確定問題是否在函數內,直接運行完函數

假如我們現在的調試過程一直在循環之后,我們想跳出這個for循環

那么我們可以輸入命令until 12我們直接跳到我們的12行代碼處

until局部區域快速執行

就是直接將我們的循環跑完了,然后就跳轉到我們指定的行

在這里插入圖片描述
我們利用display獲取我們的變量的數據,依次進行獲取

然后我們然后使用n命令,后面一直回車n進行調試

我們發現我們可以查看我們當時每一個display的數據

所以我們的display就是查看我們的上下文的數據

我們發現我們每次display的話他會多出一個編號的

如果我們不想看到哪一個數據的話我們可以輸入命令undisplay 對應的編號

然后我們輸入命令n的時候我們被刪除的常顯示的數據就不會顯示出來了

在這里插入圖片描述
在這里插入圖片描述

我們可以使用info locals查看我們當前函數內所有的臨時變量

以下是整理后的 GDB 命令分類及示例,以表格形式展示:

類別命令作用示例
代碼查看與導航list/l顯示源代碼(每次10行)list/l 10
list/l 函數名列出指定函數的源代碼list/l main
list/l 文件名:行號列出指定文件的某行代碼list/l mycmd.c:1
程序運行與調試run/r從程序開始連續執行run
next/n單步執行,不進入函數內部next
step/s單步執行,進入函數內部step
finish執行到當前函數返回,然后停止finish
continue/c從當前位置開始連續執行程序continue
until 行號執行到指定行號until 20
斷點管理break/b [文件名:]行號在指定行號設置斷點break 10break test.c:10
break/b 函數名在函數開頭設置斷點break main
info break/b查看當前所有斷點的信息info break
delete/d breakpoints刪除所有斷點delete breakpoints
delete/d breakpoints n刪除編號為 n 的斷點delete breakpoints 1
disable breakpoints禁用所有斷點disable breakpoints
enable breakpoints啟用所有斷點enable breakpoints
變量與表達式print/p 表達式打印表達式的值print start+end
p 變量名打印指定變量的值p x
set var 變量=值修改變量的值set var i=10
display 變量名跟蹤顯示指定變量值(每次停止時)display x
undisplay 編號取消指定編號的變量顯示undisplay 1
調試信息backtrace/bt查看當前執行棧的各級函數調用及其參數backtrace
info/i breakpoints查看當前設置的斷點列表info breakpoints
info/i locals查看當前幀的局部變量值info locals
退出調試quit退出 GDB 調試器quit

此表格分類明確,便于快速查詢和理解。如需補充或調整,請隨時告知!

常見的技巧

watch 監視某一變量

執行監視一個表達式(如變量)的值,如果監視的表達式在程序運行期間的值發生變化,GDB會暫停程序的執行,并通知使用者

我們現在想看某個變量是否變化,變化的話就告訴我

我們使用命令watch result

給我們的result打一個硬件斷點,當我們的result發生變化的時候我們可以知道

而且我們使用info b可以發現我們多了一個類型為hw watchpoint的斷點,就是給result監控的

在這里插入圖片描述
只要我們的這個result發生變換了我們都會第一時間被系統通知到的

新的值和舊的值

在這里插入圖片描述

set var確定問題原因

下面我們確定問題是出在flag上面的

那么我們使用set var flag=1在不修改源代碼的情況下對我們的flag進行重新賦值的操作

便于我們這里的檢驗

然后發現確實是flag的問題

改完我們的flag我們的結果就是符合預期的

在這里插入圖片描述

條件斷點

現在我們想在循環中直接查看當我們的i是14的時候我們的result的結果是多少

那么我們可以使用我們的條件斷點進行判斷操作

輸入命令b 13 if i == 10

我們對13行進行打斷點,當我們的i=10的時候

此時info b我們可以發現多了一個條件斷點

在這里插入圖片描述
我們直接一個c回車,我們可以發現我們當前的i就是等于10了

c就是直接跳轉到下一個斷點

在這里插入圖片描述
這種斷點我們照樣是可以使用我們的d 2進行條件斷點的刪除的操作

除此之外,我們還可以使用condition直接給我們已經設置好了的斷點添加條件

下面我們使用命令condition 4 i=10給4號斷點設置一個條件 ,條件是i=10

直接利用condition給我們已經存在的斷點設置條件

在這里插入圖片描述

Cgdb是分屏操作的

上屏是代碼,下屏是調試命令窗口

我們默認是在調試命令窗口屏的

我們可以按下ESC回到我們的代碼屏

輸入i回到我們的調試窗口屏

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/65946.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/65946.shtml
英文地址,請注明出處:http://en.pswp.cn/web/65946.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Maui】動態菜單實現(綁定數據視圖)

前言 .NET 多平臺應用 UI (.NET MAUI) 是一個跨平臺框架&#xff0c;用于使用 C# 和 XAML 創建本機移動和桌面應用。 使用 .NET MAUI&#xff0c;可從單個共享代碼庫開發可在 Android、iOS、macOS 和 Windows 上運行的應用。 .NET MAUI 是一款開放源代碼應用&#xff0c;是 X…

Bash語言的語法糖

Bash語言的語法糖 引言 在現代編程語言中&#xff0c;“語法糖”是一個非常常見的術語&#xff0c;它指的是那些使代碼更加易讀、易寫的語法特性。盡管這些特性并不改變語言的功能&#xff0c;但它們能顯著提升開發者的編程體驗。在眾多編程語言中&#xff0c;Bash&#xff0…

linux---Nginx詳細教程(包含安裝,網站部署)

Nginx是一個高性能的HTTP和反向代理服務器&#xff0c;也可以用作郵件代理服務器&#xff0c;其以占有內存少、并發能力強、穩定性高、豐富的功能集、低系統資源消耗而聞名。以下是對Nginx的詳細教程&#xff1a; 一、Nginx簡介 Nginx由俄羅斯人開發&#xff0c;第一個公開版…

RNN之:LSTM 長短期記憶模型-結構-理論詳解-及實戰(Matlab向)

0.前言 遞歸&#xff01;循環神經網絡Recurrent Neural Network 循環神經網絡&#xff08;又稱遞歸神經網絡&#xff0c;Recurrent Neural Network&#xff0c;RNN&#xff09;。是一種用于處理序列數據的神經網絡結構&#xff0c;具有記憶功能&#xff0c;能夠捕捉序列中的時…

泛目錄和泛站有什么差別

啥是 SEO 泛目錄&#xff1f; 咱先來說說 SEO 泛目錄是啥。想象一下&#xff0c;你有一個巨大的圖書館&#xff0c;里面的書架上擺滿了各種各樣的書&#xff0c;每一本書都代表著一個網頁。而 SEO 泛目錄呢&#xff0c;就像是一個超級圖書管理員&#xff0c;它的任務就是把這些…

初識@ffmpeg/ffmpeg庫

前言 FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,并且能夠利用它們來創建一個新的流媒體格式的自由軟件項目,它被廣泛應用在視頻處理、音頻處理以及直播領域。其中,@ffmpeg/ffmpeg 是一個將 FFmpeg 編譯為 WebAssembly(WASM)的庫,可支持幾乎所有的音視頻格式。 安裝…

【圖像去噪】論文復現:反向擴散中加入MAP將擴散模型從高斯去噪推廣到真實去噪!DiffusionVI的Pytorch源碼復現,跑通源碼,梳理理論,單卡可執行!

請先看【專欄介紹文章】:【圖像去噪(Image Denoising)】關于【圖像去噪】專欄的相關說明,包含適配人群、專欄簡介、專欄亮點、閱讀方法、定價理由、品質承諾、關于更新、去噪概述、文章目錄、資料匯總、問題匯總(更新中) 完整代碼和訓練好的模型權重文件下載鏈接見本文底…

Windows 藍牙驅動開發-簡介

藍牙(英語&#xff1a;Bluetooth)是一種無線通信技術標準&#xff0c;用來讓固定與移動設備&#xff0c;在短距離間交換資料&#xff0c;以形成個人局域網(PAN)。其使用短波特高頻(UHF)無線電波&#xff0c;經由2.4至2.485 GHz的ISM頻段來進行通信。1994年由電信商愛立信(Erics…

【Vue】全局/局部組件使用流程(Vue2為例)

全局組件和局部組件區別 如何使用 全局組件&#xff1a;全局注冊后&#xff0c;可以在任意頁面中直接使用。局部組件&#xff1a;在頁面中需要先導入子組件路徑&#xff0c;注冊組件才能使用。 適用場景 全局組件&#xff1a;適用于高頻使用的組件&#xff0c;如導航欄、業…

【Pytorch實用教程】PyTorch 中如何輸出模型參數:全面指南

文章目錄 PyTorch 中如何輸出模型參數:全面指南1. 為什么需要輸出模型參數?2. PyTorch 中輸出模型參數的方法2.1 使用 `model.parameters()` 輸出所有參數2.2 使用 `model.named_parameters()` 輸出參數名稱和值2.3 使用 `model.state_dict()` 輸出模型的參數字典2.4 輸出特定…

vscode vue 自動格式化

vscode vue 自動格式化 安裝Prettier和Vetur插件 選擇設置&#xff0c;并且轉到編輯文件。增加如下內容。 {"editor.formatOnSave": true,"editor.defaultFormatter": "esbenp.prettier-vscode","[vue]": {"editor.defaultFor…

1、docker概念和基本使用命令

docker概念 微服務&#xff1a;不再是以完整的物理機為基礎的服務軟件&#xff0c;而是借助于宿主機的性能。以小量的形式&#xff0c;單獨部署的應用。 docker&#xff1a;是一個開源的應用容器引擎&#xff0c;基于go語言開發的&#xff0c;使用時apache2.0的協議。docker是…

Genymotion配套VirtualBox所在地址

在 Genymotion打開虛擬機前需要先打開VirtualBox中的虛擬機 C:\Program Files\Oracle\VirtualBox\VirtualBox.exe 再開啟genymotion中的虛擬機開關

【Linux】深刻理解軟硬鏈接

一.軟硬鏈接操作 1.軟連接 touch 創建一個文件file.txt &#xff0c;對該文件創建對應的軟鏈接改怎么做呢&#xff1f; ln -s file.txt file-soft.link .給對應文件創建軟連接。 軟連接本質就是一個獨立的文件&#xff0c;因為我們對應的軟連接有獨立的inode&#xff0c;他…

linux下MySQL的數據存放

在 Linux 下安裝的 MySQL&#xff0c;數據表的數據默認存放在 My曉SQL 數據庫的**數據目錄**&#xff08;Data Directory&#xff09;中。具體來說&#xff0c;MySQL 會將所有數據庫的數據存儲在一個由 MySQL 配置文件中指定的目錄里。該目錄包含了所有數據庫的表、索引、日志等…

第三十六章 Spring之假如讓你來寫MVC——攔截器篇

Spring源碼閱讀目錄 第一部分——IOC篇 第一章 Spring之最熟悉的陌生人——IOC 第二章 Spring之假如讓你來寫IOC容器——加載資源篇 第三章 Spring之假如讓你來寫IOC容器——解析配置文件篇 第四章 Spring之假如讓你來寫IOC容器——XML配置文件篇 第五章 Spring之假如讓你來寫…

快速上手 HarmonyOS 應用開發

一、DevEco Studio 安裝與配置 1. DevEco Studio 簡介 DevEco Studio 是 HarmonyOS 的一站式集成開發環境&#xff08;IDE&#xff09;&#xff0c;提供了豐富的工具和功能&#xff0c;支持 HarmonyOS 應用開發的全流程。 2. DevEco Studio 下載與安裝 下載地址&#xff1a…

Java Web開發進階——錯誤處理與日志管理

錯誤處理和日志管理是任何生產環境中不可或缺的一部分。在 Spring Boot 中&#xff0c;合理的錯誤處理機制不僅能夠提升用戶體驗&#xff0c;還能幫助開發者快速定位問題&#xff1b;而有效的日志管理能夠幫助團隊監控應用運行狀態&#xff0c;及時發現和解決問題。 1. 常見錯誤…

圖解Git——分支的新建與合并《Pro Git》

?分支的新建與合并 先引入一個實際開發的工作流&#xff1a; 開發某個網站。為實現某個新的需求&#xff0c;創建一個分支。在這個分支上開展工作。 正在此時&#xff0c;你突然接到一個電話說有個很嚴重的問題需要緊急修補。你將按照如下方式來處理&#xff1a; 切換到你…

C#使用實體類Entity Framework Core操作mysql入門:從數據庫反向生成模型2 處理連接字符串

初級代碼游戲的專欄介紹與文章目錄-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代碼都將會位于ctfc庫中。已經放入庫中我會指出在庫中的位置。 這些代碼大部分以Linux為目標但部分代碼是純C的&#xff0c;可以在任何平臺上使用。 源碼指引&#xff1a;github源…