Linux C一站式编程(第十章 GDB)

gcc -g main.c -o main

在编译的时候必须加上-g,生成的目标文件才能够进行调试。(我们调试的是目标文件)
-g选项的作用是在目标文件中加入源代码的信息,保证gdb能找到源文件。

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


$ gcc -g main.c -o main
$ gdb main
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
(gdb) 

gdb提供一个类似shell的命令行环境,上面的(gdb)就是提示符


输入help可以查看命令的类别

(gdb) help      //查看命令的类别
(gdb) help files   //进一步查看具体的命令(这里的命令是files)
(gdb) list 1  //从第一行列出源代码,列至11行(一次列10行)
(gdb) list  //接着上一次列出的地方列出接下来十行,如果不够,那么截止;
  • 在提示符下直接敲回车表示用适当的参数重复上一条命令。
  • 允许简写(list 写成 l)
  • list后加函数名,那么直接显示关于函数的源代码。
  • quit:退出

  • 采用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)进入某一个栈帧(用数字表示),在栈帧中可以查看对应函数的局部变量及其对应信息。
  • 用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 序号;

    扫描二维码关注公众号,回复: 2869230 查看本文章
  • 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进行执行下次操作;


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

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


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

猜你喜欢

转载自blog.csdn.net/lansehuanyingyy/article/details/81450601