GDB随笔(一)

gcc -g main.c -o main
  • 在编译的时候必须加上-g,生成的目标文件才能够进行调试。(我们调试的是目标文件)
  • -g选项的作用是在目标文件中加入源代码的信息,保证gdb能找到源文件。
  • -o选项,相当于指定一个文件作为目标文件。

可以做一个实验:由main.c生成main(-g),然后将m**在目标文件中加入源代码的信息,保证gdb能找到源文件。ain.c改成其他名字,然后调用gdb main,就会发现对gdb使用命令(list),提示:没有那个目录或文件;但是再将源文件改回原来的名称,那么命令也可以正常调用;说明,-g选项不是把源文件放入目标代码中,而是建立一种联系,


命令种类:GDB中将命令划分为几个类别,可以通过help进行查看。此外,还可以通过help还可以查询具体某个指令的功能。

(gdb) help
List of classes of commands:

aliases -- Aliases of other commands
breakpoints -- Making program stop at certain points
data -- Examining data
files -- Specifying and examining files
internals -- Maintenance commands
obscure -- Obscure features
running -- Running the program
stack -- Examining the stack
status -- Status inquiries
support -- Support facilities
tracepoints -- Tracing of program execution without stopping the program
user-defined -- User-defined commands

Type "help" followed by a class name for a list of commands in that class.
Type "help all" for the list of all commands.
Type "help" followed by command name for full documentation.
Type "apropos word" to search for commands related to "word".
Command name abbreviations are allowed if unambiguous.

list命令,这是一个非常简单而且基础的命令。
其功能:列出从某一行开始接下来十行的内容或者某个函数的内容。

list 1  表示列举第一行至第十行的内容
list 表示从上次list结束的位置开始显示十行内容,初始为1
list  function_name   显示某个函数的内容
简写:l

  • 采用start命令进行断点调试;temporary breakpoint表示下一条将要执行的指令。
(gdb) start
Temporary breakpoint 1 at 0x6de: file HelloWorld.c, line 12.
Starting program: /home/bluephantom/文档/C编程一站式/gdbHelloWorld 

Temporary breakpoint 1, main () at HelloWorld.c:12
12  {
  • 可通过next(n)命令进行执行下一条指令
  • 可通过step(s)命令进入函数中去执行
  • 可通过backtrace(bt)命令查询函数状态
(gdb) bt
#0  add_range (low=1, high=10) at main.c:6
#1  0x080483c1 in main () at main.c:14
可见当前的add_range函数是被main函数调用的,main传进来的参数是
low=1,high=10。main函数的栈帧编号为1,add_range的栈帧编号为0。
后调用的在上层!
  • 用info命令(简写为i)查看各种信息

    • i locals:查看局部变量信息
    • i breakpoints:查看断点信息
    • i watchpoints:查看观察点信息
  • 用frame命令(简写f)进入某一个栈帧(用数字表示),在栈帧中可以查看对应函数的局部变量及其对应信息。(使用frame并没有使程序跳转到此栈帧,而是只是为了查看某些信息)

  • 用print命令(简写p)+ 局部变量,打印某一个局部变量的值。

  • 用finsih命令,可以结束当前函数,回到被调用位置;

  • 用set var命令,后面加变量可以直接进行赋值,对于数组,也可以使用下标进行单独赋值;
    (gdb) set var result[0]=50
    这里写图片描述


  • 采用display+变量,可以跟踪显示变量的值,每一次next都会将其值显示出来。采用undisplay可以取消跟踪(通过加对应的标号,单个取消;否则全部取消)
(gdb) display i
2: i = 0
  • 断点(breakpoint)调试:使用break命令(简写b)+行数(函数名),在该行/函数开头设置断点,然后搭配continue(简写c) ; 可以通过info(info breakpoints)查看设置了多少断点;
  • 删除断点:delete breakpoints 断点标号,

  • 断点加单步”是使用调试器的基本方法。至于应该在哪里设置断点,怎么知道哪些代码可以跳过而哪些代码要慢慢走,也要通过对错误现象的分析和假设来确定,就像以前分析确定在哪里插入printf语句一样。

  • 禁用断点(暂时使其无作用),disable breakpoints 序号; 启用断点:enable breakpoints 序号;

  • break 9 if sum != 0 :设置断点在满足某个条件时才激活

  • run命令(简写为r)重新从程序开头连续执行
    这里写图片描述


#include <stdio.h>

int main(void)
{
    int sum = 0, i = 0;
    char input[5];

    while (1) {
        sum = 0;
        scanf("%s", input);
        for (i = 0; input[i] != '\0'; i++)
            sum = sum*10 + input[i] - '0';
        printf("input=%d\n", sum);
    }
    return 0;
}


$ gdb main
......
(gdb) start
Breakpoint 1 at 0x80483b5: file main.c, line 5.
Starting program: /home/akaedu/main 
main () at main.c:5
5       int sum = 0, i = 0;
(gdb) n
9           sum = 0;
(gdb) (直接回车)
10          scanf("%s", input);
(gdb) (直接回车)
12345
11          for (i = 0; input[i] != '\0'; i++)
(gdb) p input
$1 = "12345"


(gdb) x/7b input
0xbfb8f0a7: 0x31    0x32    0x33    0x34    0x35    0x00    0x00

x命令:打印存储器中的内容。7b是打印格式,b表示每个字节一组,7表示打印7组。开头表示的是起始地址。
观察点(watchpoint)与断点:断点是当程序执行到某一代码行时中断,而观察点是当程序访问某一存储单元时中断。(观察点跟踪单元)
watch + 变量 :观察某个变量
观察点也是通过continue进行执行下次操作;


  • 段错误(segment fault):在gdb中运行,遇到段错误会自动停下来。这个时候可以调用backtrace(bt)查看是在哪个函数内发生错误,然后进行修改。

  • 如果某个函数中发生访问越界,很可能并不立即产生段错误,而在函数返回时却产生段错误。


until(简写u):执行到某一行为止;(可以加函数名,也可以加行号)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章