日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GDB调试使用详解

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GDB调试使用详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

參考:C語言gdb調試之精髓(常用命令、多進程、多線程、程序日志)
作者:C語言技術網
發布時間: 2020-07-15 17:13:30
網址:https://www.bilibili.com/video/BV1ei4y1V758?from=search&seid=4037367131025904962
以及:http://www.freecplus.net/b72113dda88a43b48728e0552fd8a74c.html

參考:Linux的調試器–GDB等
作者:一只青木呀
發布時間: 2020-07-14 15:31:01
網址:https://blog.csdn.net/weixin_45309916/article/details/107338210

目錄

  • Linux的調試器
    • 概念
    • 安裝GDB增強工具 (gef)
      • 簡單的安裝方法(我的Linux是Ubuntu18.04)
    • 嘗試使用gdb進行小程序的調試
    • GDB的命令
    • GDB的基本命令
  • GDB的簡單使用
    • 0.編譯hello.c
    • 1.啟動GDB
    • 2.下斷點
    • 3.讓程序運行起來
    • 4.此時需要往下運行
    • 5.查看運行中程序的變量
    • 6.運行時程序的打印會在最上面顯示
    • 7.退出gdb
    • 8.補充一點(設置參數)
  • GDB多進程調試
    • 1.編譯
    • 2.啟動gdb
    • 3.下斷點(我們以man函數為例)
    • 4.運行
    • 5.選擇是走子進程還是父進程
  • GDB多線程調試
    • 1.編譯
    • 2.開始調試
    • 3.選擇線程

Linux的調試器

概念

程序員寫在編寫程序的時候不可能是一帆風順的,gcc編譯器可以發現程序代碼的語法錯誤,但不能發現程序的業務邏輯錯誤,調試程序是軟件開發的內容之一。調試程序的方法有很多種,例如可以用printf語句跟蹤程序的運行步驟和顯示變量的值,本章節介紹一個功能強大的調試工具gdb。

  • 基于命令行的調試方法
  • 所有的調試都是可以進行腳本編寫的
  • 能夠調試所有架構的代碼
  • 有三種調試方法供大家選擇
  • GDB支持遠程調試,支持與IDA進行聯調

安裝GDB增強工具 (gef)

一般來說,gdb啟動起來就是這樣的樣子

  • gdb的一直都非常強大,但是每一步調試,可能有一些要查看的信息,如果每一步都要手動輸入命令,未免有點麻煩,所以就出現了插件,把某一些經常要查看的信息每一步都自動幫你顯示出來,方便調試

簡單的安裝方法(我的Linux是Ubuntu18.04)

1、切換到用戶權限
2、切換到用戶家目錄 比如/home/qingmu
3、保持網絡通暢,然后只要輸入下面的命令 就行

git clone https://github.com/gatieme/GdbPlugins.git ~/GdbPlugins 從git上面下載一些插件 (沒有git 可以自行安裝)apt-get install git


克隆完之后,會在你當前目錄下面有GdbPlugins 這個文件,并且里面會有這幾個文件

  • 這樣就算ok了,里面三個插件,當你想要用某一個插件的時候,只要輸入對應命令就行
  • 這里我們主要使用gef 我們執行
echo "source ~/GdbPlugins/gef/gef.py" > ~/.gdbinit

然后我們啟動gdb就行了

至此gef插件安裝完畢

嘗試使用gdb進行小程序的調試

gcc -g的選項 gdb gdb-test 一些GDB的命令

GDB的命令

啟動方法

本地普通啟動 gdb 本地段錯誤文件啟動 gdb core attch方式啟動 gdb 遠程啟動 gdbserver 0.0.0.0:1234 /path/to/file

啟動選項

–symbols < file > -s < file > 從指定文件中讀取符號表 -se < file > 從指定文件中讀取符號表信息,并把它們用在可執行文件中 –core < file > 調試時core dump的core文件 –directory < directory> -d < directory> 加入一個源文件的搜索路徑。默認搜索路徑是環境變量中PATH所定義的路徑 詳細的開關可以使用gdb --help

基本命令

set listsize 設置調試中可以查看的行數 set args 10 20 30 40 50 設置程序所需要的參數 path show paths save breakpoint name.bp gdb elf -x name.bp print § 查看運行數據 print *array@10 查看數組 print file::variable 查看file文件下的variable x/n、f、u 查看內存 n 是一個正整數,表示顯示內存的長度,也就是說從當前地址向后顯示幾個地址的內容。 f 表示顯示的格式,跟print 的格式參數相同 u 表示從當前地址往后請求的字節數,如果不指定的話,GDB默認是4個bytes。u參數可以用下面的字符來代替,b表示單字節,h表示雙字節,w表示四字節,g表示八字節。當我們指定了字節長度后,GDB會從指內存定的內存地址開始,讀寫指定字節,并把其當作一個值取出來。

GDB的基本命令

Linux程序發布流程
確定程序是否存在符號表
readelf -s test-1
生成符號表
objcopy --only-keep-debug test-1 test-1.symbol
生成發布程序
objcopy --strip-debug test-1 test-release
使用符號表進行程序debug
gdb -q --symbol=test-1.symbol --exec=test-release
GDB中暫停/恢復程序運行
斷點
條件斷點
break if
info breakpoints
delete
disable
enable

觀察點
watch 地址
info watchpoints
rwatch

捕捉點
catch event
throw 拋出一個C++的異常 catch throw
catch 捕捉一個C++的異常 catch catch
exec 調用系統調用exev時停止 catch exec
fork 調用系統調用fork時停止 catch fork
load/load libname 載入動態鏈接庫時 catch load / catch load libname

暫停命令
commands bnum
.
.
.
.
end

GDB的簡單使用

0.編譯hello.c

gcc -g hello.c -o hello

注意:編譯的時候一定要加上 -g 選項,使之加入符號表,否賊調試的時候看不到程序的源代碼。為了更方便的使用gdb 一定要安裝gdb插件gef

以hello.c為例

1.啟動GDB

gdb hello //hello 是hello.c的可執行文件

2.下斷點

也就是程序運行到哪,我們以man函數為例
也可以指定在哪一行下斷點。

b

info breakpoints 可查看下的斷點

3.讓程序運行起來

r


此時程序就運行起來了

4.此時需要往下運行

" n " :執行一條語句,碰到函數會直接運行函數
" s ":執行下一條語句,碰到函數會進入到函數中

5.查看運行中程序的變量

" p "

6.運行時程序的打印會在最上面顯示

7.退出gdb

q

8.補充一點(設置參數)

如果程序需要傳入參數那么 “set args” 在啟動gdb之后就可以設置參數
例如我需要傳遞兩個參數:

中間用空格隔開就可以了

GDB多進程調試

下面以process.c為例

#include<stdio.h> #include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<sys/wait.h>int main() {pid_t pid = fork();//創建子進程if(pid == -1){perror("fork error");return -1;}else if(pid == 0)//child{printf("i am a child:my pid is %d,my father is %d\n",getpid(),getppid());}else//father{printf("i am a father:my pid is %d\n",getpid());wait(NULL);//等待子進程}return 0;}

1.編譯

gcc -g process.c -o process //一定要加-g 把符號表載入代碼

2.啟動gdb

gdb process

3.下斷點(我們以man函數為例)

b main

4.運行

r

5.選擇是走子進程還是父進程

fork()函數
返回值為0:子進程
返回值大于0:父進程
返回值小于0:創建失敗
函數運行是他自己是走父進程還是子進程是不確定的,所以我們需要讓他按照自己的想法運行,這是我們就按自己的需要是走父進程還是子進程

跟著父進程去運行

set follow-fork-mode parent

跟著子進程運行

set follow-fork-mode child

設置之后我們就n往下運行就可以進入子進程

GDB多線程調試

下面以thread.c為例

#include<stdio.h> #include<pthread.h>void* thread1(void* arg) {printf("i am thread1,my tid is %u\n",pthread_self());int i=0;int result=0;for(;i<100;i++){result += i;}printf("thread1 result = %d\n",result);return NULL; }void* thread2(void* arg) {printf("i am thread2,my tid is %u\n",pthread_self());int i=0;int result=0;for(;i<100;i++){result ^= i;}printf("thread2 result = %d\n",result);return NULL; }int main() {pthread_t tid1,tid2;pthread_create(&tid1,NULL,thread1,NULL);//創建線程1pthread_create(&tid2,NULL,thread2,NULL);//創建線程2pthread_join(tid1,NULL);//等待線程1pthread_join(tid2,NULL);//等待線程2 return 0; }

1.編譯

gcc -g thread.c -o thread -lpthread //線程庫不是內核自帶的 要自己加上

2.開始調試

gdb thread

3.選擇線程

線程比較簡單 想看哪個線程就把斷點下到哪個線程的函數上

跟線程1運行

b thread1

跟線程2運行

b thread2

這里我們跟線程1運行

這里我們就跟進了線程1了

可以通過:"info threads"命令來查看正在運行程序中線程信息
其余的就是基本操作了
p 打印想看的數據
x查看對應的內存等等

總結

以上是生活随笔為你收集整理的GDB调试使用详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。