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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

【C语言基础】gdb调试工具的使用

發布時間:2024/9/27 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C语言基础】gdb调试工具的使用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

gdb調試教程

快速入門

要想快速入門gdb調試,可以直接翻閱基本案例:采內存

介紹

GDB是一個由GNU開源組織發布的、UNIX/LINUX操作系統下的、基于命令行的、功能強大的程序調試工具。 對于一名Linux下工作的c/c++程序員,gdb是必不可少的工具

常用指令

  • shell 指令
指令用法介紹
gdbgdb +${exe}對生成的可執行文件進行調試
gdb -qgdb -q +${exe}對生成的可執行文件進行調試
表示不打印gdb版本信息,界面較為干凈;
  • gdb指令
指令用法介紹
斷點設置
breakbreak +Line<br>break+{Line}<br>break +Line<br>break+{func}可以對行號和函數進行設置斷點
程序運行
runrun / r首次運行程序,運行到第一個斷點
continuecontinue / c繼續運行程序,運行到下一個斷點
nextnext / n單步跳過,(執行一步程序,遇到函數,直接完成函數操作,不會進入函數)
stepstep / s單步進入,(執行一步程序,遇到函數會進入)
untiluntil / u + ${Line}跳出循環體,并跳到循環體外部的某一行
變量查看
printprint +變量打印變量的值
whatiswhatis +變量打印變量的類型
quitquit / q退出
可視化
layout src調試的時候同時顯示源代碼窗口,但是必須run之后才會顯示

基本案例:采內存

0. 源碼

本案例以下文段錯誤(采內存)源碼進行介紹如何進行gdb調試。

通常在復雜程序調用中,指針的操作容易導致編程人員對內存空間的使用造成困擾和混亂,因此指針操作是導致內存異常問題最為常見的因素也是最難定位的因素。

源代碼如下:

在本案例中,main函數里的my_user指針在addUser函數里進行資源申請。雖然成功申請到了堆中的空間。但是因為my_user是作為參數傳入,因此在函數返回時,my_user又重新指向了NULL,而非堆上的空間地址導致運行發生段錯誤。

#include <stdio.h> #include <stdlib.h>typedef struct User {int id;int age; } User;void addUser(User *user, int id, int age) {user = (User *)malloc(sizeof(User));user->id = id;user->age = age;printf("id = %d, age = %d\n", user->id, user->age); }int main() {printf("gdb demo\n");User *my_user = NULL;addUser(my_user, 10, 20);printf("id = %d, age = %d\n", my_user->id, my_user->age);return 0; }

1. 編譯

要想使用gdb調試功能,需要在gcc編譯器添加-g參數,或者在cmake里編譯成debug模式。

>> gcc -g -o main main.c

2. 打開gdb調試

>> gdb main >> gdb -q main # 表示不打印gdb版本信息,界面較為干凈;

3. gdb 設置斷點

  • break
  • info breakpoints
# 使用 break 或者 b 進行設置斷點。 # 可以對函數進行打點,或者對代碼行進行打點。 # 我們可以使用info breakpoints查看當前所有的斷點信息 (gdb) b addUser Breakpoint 1 at 0x752: file gdb_test.c, line 11. (gdb) b 13 Breakpoint 2 at 0x769: file gdb_test.c, line 13. (gdb) b 20 Breakpoint 3 at 0x7aa: file gdb_test.c, line 20. (gdb) info breakpoints Num Type Disp Enb Address What 1 breakpoint keep y 0x0000000000000752 in addUser at gdb_test.c:11 2 breakpoint keep y 0x0000000000000769 in addUser at gdb_test.c:13 3 breakpoint keep y 0x00000000000007aa in main at gdb_test.c:20

4. 運行

  • run
  • continue
  • next
  • step
# 當我們設置完斷點進行調試的時候,首先要執行run函數開啟程序進程,run會執行到第一個斷點位置 # 然后我們可以執行next 或者 continue 或者 step進行推進程序 # continue: 運行到下一個斷點 # next: 單步跳過,(執行一步程序,遇到函數,直接完成函數操作,不會進入函數) # step: 單步進入,(執行一步程序,遇到函數會進入) (gdb) run Starting program: /home/rodney/ProjectCode/Cproject/C_coding/gcc&g++&gdb_block/bug1/main gdb demoBreakpoint 3, main () at gdb_test.c:20 20 User *my_user = NULL; (gdb) n 22 addUser(my_user, 10, 20); (gdb) c Continuing.Breakpoint 1, addUser (user=0x0, id=10, age=20) at gdb_test.c:11 11 user = (User *)malloc(sizeof(User));(gdb) c Continuing.Breakpoint 2, addUser (user=0x555555756420, id=10, age=20) at gdb_test.c:13 13 user->age = age;(gdb) n 14 printf("id = %d, age = %d\n", user->id, user->age); (gdb) n id = 10, age = 20 15 } (gdb) n main () at gdb_test.c:23 23 printf("id = %d, age = %d\n", my_user->id, my_user->age); (gdb) nProgram received signal SIGSEGV, Segmentation fault. 0x00005555555547cc in main () at gdb_test.c:23 23 printf("id = %d, age = %d\n", my_user->id, my_user->age);

從上文可以看出是23行打印發生了報錯,那么如何確定23行的打印發生了什么具體錯誤,可以使用print和whatis進行打印顯示。

5. 打印和顯示變量信息

  • print 打印變量的值
  • whatis 打印變量的類型
# 從打印的信息可以看出,這里my_user是個空指針,因此訪問出現上文的段錯誤。 (gdb) whatis my_user type = User * (gdb) whatis my_user->id type = int (gdb) print my_user $1 = (User *) 0x0 (gdb) print my_user->id Cannot access memory at address 0x0

總結

以上是生活随笔為你收集整理的【C语言基础】gdb调试工具的使用的全部內容,希望文章能夠幫你解決所遇到的問題。

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