linux下shell编程调试方法,gdb工具的使用

前言


windows 的界面操作非常丰富,对程序开发也是如此,各种强大的 IDE 真是非常方便。转入 linux 编程后,没有界面,用 vim gcc 搞程序开发,一开始还真是不适应。现在用的多了,反而习惯用 linux 开发了。但是,没法调试程序真是太痛苦了,只能逐行加 printf。。。

其实早就听说 linux 程序开发有 gdb 工具可以用于调试,一直没有去了解。今天加 printf 实在是加到崩溃,肯定要了解一下的。了解后,才发现,gdb 并不复杂,很容易用的工具。好用的工具肯定都是容易使用的。

gdb 是什么,可以做什么?


gdb 就是一个调试工具,一般来说,GDB主要帮助你完成下面四个方面的功能:

  • 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
  • 可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
  • 当程序被停住时,可以检查此时你的程序中所发生的事。
  • 你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。

gdb 调试实战项目,牛刀小试


c 语言小 demo

咱们先用 c 语言随便写一个小 demo 作为测试对象:

// 文件名 test.c
#include <stdio.h>

int GetSum(char num1, char num2)
{
    int res = 0;
    res = num1 + num2;
    return res;
}

int main()
{
    char i = 10, j = 10;
    int sum = 0;

    i ++;
    j ++;   
    sum = GetSum(i, j); 
    printf("i + j = %d\n", sum);    

    return 0;
}

很简单的程序,如果打算使用 gdb 调试它,记得编译的时候加上 -g 选项。

gcc -g -Wall -o test test.c

得到可执行程序后,就可以使用 gdb 调试了。

gdb 调试命令


gdb 全速运行

(gdb)run,也可只输入 r,程序会开始运行,停在第一个断点处。
(gdb)continue,也可只输入 c,程序继续运行,停在下一个断点处。

gdb 添加搜索代码源文件路径

(gdb)directory [path],也可输入 dir [path],将 path 添加到搜索目录中。

gdb 打印代码

gdb + 可执行程序即可进入 gdb 调试:
输入 l 可以打印出代码,如果想输出指定行号的代码,可以加上数字,例如 l 5

gdb 断点

下断点有两种方式:
  • (gdb)break(也可只输入b) + 函数名
  • (gdb)break + 行号
  • (gdb)break + 条件。这个命令必须在变量i被定义之后才会成功运行,为了解决这个问题,首先在变量 i 被定义的后一行设置中断,然后使用run命令运行程序,程序暂停后就可以使用watch i==99设置断点了。例如

    • break 7 if i==99
    • watch i==99
查看断点
  • 显示当前gdb的断点信息:
    (gdb) info break
  • 删除指定的某个断点:
    (gdb) delete breakpoint 1
  • 该命令将会删除编号为1的断点,如果不带编号参数,将删除所有的断点
    (gdb) delete breakpoint
  • 禁止使用某个断点
    (gdb) disable breakpoint 1
    该命令将禁止断点1,同时断点信息的 (Enb)域将变为 n
  • 允许使用某个断点
    (gdb) enable breakpoint 1
    该命令将允许断点1,同时断点信息的 (Enb)域将变为 y
  • 清除源文件中某一代码行上的所有断点
    (gdb)clear number
    注:number 为源文件的某个代码行的行号

变量检查赋值编辑

  • whatis:识别数组或变量的类型
  • ptype:比whatis的功能更强,他可以提供一个结构的定义
  • set variable = value:将值赋予变量
  • print variable = value or p variable = value : 除了显示一个变量的值外,还可以用来赋值

单步执行编辑

  • next 不进入的单步执行
  • step 进入的单步执行如果已经进入了某函数,而想退出该函数返回到它的调用函数中,可使用命令finish

函数调用编辑

  • call name 调用和执行一个函数
    (gdb) call gen_and_sork(1234,1,0)
    (gdb) call printf(“abcd”)
    =4
  • finish 结束执行当前函数,显示其返回值(如果有的话)

gdb 调试linux程序实战

咱们以上面的小 demo 为例。

首先看看代码,然后再 main 处和第 15 行下断点

输入 r(run) 运行,可以看出,运行停在 main 函数入口处了:

输入 n(next) 跳过,期间可以输入 l 查看代码:

来到 GetSum 函数出,输入 s(step into),进入 GetSum 函数:

输入 p(print) + 变量,可以查看变量值。

至此,基本的调试流程已经走完了,输入 run 全速运行,程序运行结束,咱们选择从头开始:

这次取消全部断点,全速运行:

可以看出,直接就运行到程序最后了。

这样,我以后就不用再一行一行输入 printf 调试了, gdb 调试 linux 程序就这样实现了。
阅读更多:   Linux笔记
已有 2 条评论
  1. […] 今天用 C 语言编程时,发现一个非常奇怪的现象:逻辑一切正常,输出却不对。采用 GDB 调试(可参考:gdb工具的使用),定位到错误,居然是乘法运算出了问题。两个数字相乘,结果却是不正确的,始终是错误的。 […]

  2. […] 今天用 C 语言编程时,发现一个非常奇怪的现象:逻辑一切正常,输出却不对。采用 GDB 调试(可参考:gdb工具的使用),定位到错误,居然是乘法运算出了问题。两个数字相乘,结果却是不正确的,始终是错误的。 […]

添加新评论

icon_redface.gificon_idea.gificon_cool.gif2016kuk.gificon_mrgreen.gif2016shuai.gif2016tp.gif2016db.gif2016ch.gificon_razz.gif2016zj.gificon_sad.gificon_cry.gif2016zhh.gificon_question.gif2016jk.gif2016bs.gificon_lol.gif2016qiao.gificon_surprised.gif2016fendou.gif2016ll.gif