日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

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

發(fā)布時(shí)間:2024/9/27 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【C语言基础】gdb调试工具的使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

gdb調(diào)試教程

快速入門

要想快速入門gdb調(diào)試,可以直接翻閱基本案例:采內(nèi)存

介紹

GDB是一個(gè)由GNU開源組織發(fā)布的、UNIX/LINUX操作系統(tǒng)下的、基于命令行的、功能強(qiáng)大的程序調(diào)試工具。 對(duì)于一名Linux下工作的c/c++程序員,gdb是必不可少的工具

常用指令

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

基本案例:采內(nèi)存

0. 源碼

本案例以下文段錯(cuò)誤(采內(nèi)存)源碼進(jìn)行介紹如何進(jìn)行g(shù)db調(diào)試。

通常在復(fù)雜程序調(diào)用中,指針的操作容易導(dǎo)致編程人員對(duì)內(nèi)存空間的使用造成困擾和混亂,因此指針操作是導(dǎo)致內(nèi)存異常問(wèn)題最為常見的因素也是最難定位的因素。

源代碼如下:

在本案例中,main函數(shù)里的my_user指針在addUser函數(shù)里進(jìn)行資源申請(qǐng)。雖然成功申請(qǐng)到了堆中的空間。但是因?yàn)閙y_user是作為參數(shù)傳入,因此在函數(shù)返回時(shí),my_user又重新指向了NULL,而非堆上的空間地址導(dǎo)致運(yùn)行發(fā)生段錯(cuò)誤。

#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調(diào)試功能,需要在gcc編譯器添加-g參數(shù),或者在cmake里編譯成debug模式。

>> gcc -g -o main main.c

2. 打開gdb調(diào)試

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

3. gdb 設(shè)置斷點(diǎn)

  • break
  • info breakpoints
# 使用 break 或者 b 進(jìn)行設(shè)置斷點(diǎn)。 # 可以對(duì)函數(shù)進(jìn)行打點(diǎn),或者對(duì)代碼行進(jìn)行打點(diǎn)。 # 我們可以使用info breakpoints查看當(dāng)前所有的斷點(diǎn)信息 (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. 運(yùn)行

  • run
  • continue
  • next
  • step
# 當(dāng)我們?cè)O(shè)置完斷點(diǎn)進(jìn)行調(diào)試的時(shí)候,首先要執(zhí)行run函數(shù)開啟程序進(jìn)程,run會(huì)執(zhí)行到第一個(gè)斷點(diǎn)位置 # 然后我們可以執(zhí)行next 或者 continue 或者 step進(jìn)行推進(jìn)程序 # continue: 運(yùn)行到下一個(gè)斷點(diǎn) # next: 單步跳過(guò),(執(zhí)行一步程序,遇到函數(shù),直接完成函數(shù)操作,不會(huì)進(jìn)入函數(shù)) # step: 單步進(jìn)入,(執(zhí)行一步程序,遇到函數(shù)會(huì)進(jìn)入) (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行打印發(fā)生了報(bào)錯(cuò),那么如何確定23行的打印發(fā)生了什么具體錯(cuò)誤,可以使用print和whatis進(jìn)行打印顯示。

5. 打印和顯示變量信息

  • print 打印變量的值
  • whatis 打印變量的類型
# 從打印的信息可以看出,這里my_user是個(gè)空指針,因此訪問(wèn)出現(xiàn)上文的段錯(cuò)誤。 (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

總結(jié)

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

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。