当前位置: 首页 > news >正文

认识linux -- 调试器 - gdb/cgdb的使用

1. 样例代码

// mycmd.c
#include <stdio.h>
int Sum(int s, int e)
{int result = 0;for(int i = s; i <= e; i++){result += i;}return result;
}int main()
{int start = 1;int end = 100;printf("I will begin\n");int n = Sum(start, end);printf("running done, result is: [%d-%d]=%d\n", start, end, n);return 0;
}

2 预备

        程序的发布⽅式有两种, debug 模式和 release 模式, Linux gcc/g++ 出来的⼆进制程
序,默认是 release 模式。
        要使⽤gdb调试,必须在源代码⽣成⼆进制程序的时候, 加上 -g 选项,如果没有添加,程序⽆法被编译
$ gcc mycmd.c -o mycmd # 默认模式,不⽀持调试
$ file mycmd
mycmd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2,
BuildID[sha1]=82f5cbaada10a9987d9f325384861a88d278b160, for GNU/Linux
3.2.0, not stripped$ gcc mycmd.c -o mycmd -g # debug模式
$ file mycmd
mycmd: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically
linked, interpreter /lib64/ld-linux-x86-64.so.2,
BuildID[sha1]=3d5a2317809ef86c7827e9199cfefa622e3c187f, for GNU/Linux
3.2.0, with debug_info, not stripped

    3 常见使用

    开始: gdb binFile
    退出: ctrl + d quit 调试命令
                   命令                                作用                样例
     list/l
    显⽰源代码,从上次位置开始,每次列出
    10⾏
    list/l 10
      list/l 函数名
    列出指定函数的源代码
    list/l main         
      list/l ⽂件名:⾏号
    列出指定⽂件的源代码
    list/l mycmd.c:1 
       r/run
    从程序开始连续执⾏run
       n/next
    单步执⾏,不进⼊函数内部, 逐过程 F10
    next
       s/step
    单步执⾏,进⼊函数内部, 逐语句 F11
    step
       break/b [⽂件名:]⾏号
    在指定⾏号设置断点
    break 10
    break test.c:10
       break/b 函数名
    查看当前所有断点的信息
    break main
        info break/b
    在函数开头设置断点
    info break
            finish         
    执⾏到当前函数返回,然后停⽌
    finish
       print/p 表达式
    打印表达式的值
    print start+end
         p 变量
    打印指定变量的值
    p x
        set var 变量=值
    修改变量的值
    set var i=10
        continue/c
    从当前位置开始连续执⾏程序
    continue
        delete/d
    breakpoints
    删除所有断点
    delete breakpoints
        delete/d
    breakpoints n
    删除序号为n的断点
    delete breakpoints 1
    disable breakpoints
    禁⽤所有断点
    disable breakpoints
    enable breakpoints
    启⽤所有断点
    enable breakpoints
    info/i breakpoints
    查看当前设置的断点列表
    info breakpoints 
    display 变量名
    跟踪显⽰指定变量的值(每次停⽌时)
    display x
    undisplay 编号
    取消对指定编号的变量的跟踪显⽰
    undisplay 1
    until X⾏号
    执⾏到指定⾏号
    until 20
    backtrace/bt
    查看当前执⾏栈的各级函数调⽤及参数
    backtrace
    info/i locals
    查看当前栈帧的局部变量值
    info locals
    quit
    退出GDB调试器
    quit

    4 常见技巧

            4.1 watch

    执⾏时监视⼀个表达式(如变量)的值。如果监视的表达式在程序运⾏期间的值发⽣变化,GDB 会暂停程序的执⾏,并通知使⽤者
    (gdb) l main
    11
    12 return result;
    13 }
    14
    15 int main()
    16 {
    17 int start = 1;
    18 int end = 100;
    19 printf("I will begin\n");
    20 int n = Sum(start, end);
    (gdb) b 20
    Breakpoint 1 at 0x11c3: file mycmd.c, line 20.
    (gdb) info b
    Num Type Disp Enb Address What
    1     breakpoint keep y 0x00000000000011c3 in main at mycmd.c:20
    (gdb) r
    Starting program: /home/whb/test/test/mycmd
    I will begin
    Breakpoint 1, main () at mycmd.c:20
    20     int n = Sum(start, end);
    (gdb) s
    Sum (s=32767, e=-7136) at mycmd.c:5
    5     {
    (gdb) n
    6     int result = 0;
    (gdb) watch result
    Hardware watchpoint 2: result
    (gdb) c
    Continuing.Hardware watchpoint 2: result
    Old value = -6896
    New value = 0
    Sum (s=1, e=100) at mycmd.c:7
    7     for(int i = s; i <= e; i++)
    (gdb) c
    Continuing.Hardware watchpoint 2: result
    Old value = 0
    New value = 1
    Sum (s=1, e=100) at mycmd.c:7
    7     for(int i = s; i <= e; i++)
    (gdb) c
    Continuing.Hardware watchpoint 2: result
    Old value = 1
    New value = 3
    Sum (s=1, e=100) at mycmd.c:7
    7     for(int i = s; i <= e; i++)
    (gdb) c
    Continuing.Hardware watchpoint 2: result
    Old value = 3
    New value = 6
    Sum (s=1, e=100) at mycmd.c:7
    7     for(int i = s; i <= e; i++)
    (gdb) info b
    Num Type Disp Enb Address What
    1     breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20
    breakpoint already hit 1 time
    2     hw watchpoint keep y result
    breakpoint already hit 4 times
    (gdb) d 2
    (gdb) info b
    Num Type Disp Enb Address What
    1     breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20breakpoint already hit 1 time
    (gdb) finish
    Run till exit from #0 Sum (s=1, e=100) at mycmd.c:70x00005555555551d2 in main () at mycmd.c:20
    20 int n = Sum(start, end);
    Value returned is $1 = 5050

    4.2 set var确定问题原因

    更改⼀下标志位,假设我们想得到 +-result
    // mycmd.c
    #include <stdio.h>
    int flag = 0; // 故意错误
    //int flag = -1;
    //int flag = 1;
    int Sum(int s, int e)
    {int result = 0;for(int i = s; i <= e; i++){result += i;}return result*flag;
    }
    int main()
    {int start = 1;int end = 100;printf("I will begin\n");int n = Sum(start, end);printf("running done, result is: [%d-%d]=%d\n", start, end, n);return 0;
    }
    (gdb) l main
    15
    16 return result*flag;
    17 }
    18
    19 int main()
    20 {
    21 int start = 1;
    22 int end = 100;
    23 printf("I will begin\n");
    24 int n = Sum(start, end);
    (gdb) b 24
    Breakpoint 1 at 0x11ca: file mycmd.c, line 24.
    (gdb) r
    Starting program: /home/whb/test/test/mycmd
    I will begin
    Breakpoint 1, main () at mycmd.c:24
    24 int n = Sum(start, end);
    (gdb) n
    25 printf("running done, result is: [%d-%d]=%d\n", start, end,
    n);
    (gdb) n
    running done, result is: [1-100]=0 # 这⾥结果为什么是0?
    26 return 0;
    (gdb) r
    The program being debugged has been started already.
    Start it from the beginning? (y or n) y
    Starting program: /home/whb/test/test/mycmd
    I will beginBreakpoint 1, main () at mycmd.c:24
    24 int n = Sum(start, end);
    (gdb) s
    Sum (s=32767, e=-7136) at mycmd.c:9
    9 {
    (gdb) n
    10 int result = 0;
    (gdb) n
    11 for(int i = s; i <= e; i++)
    (gdb)
    13 result += i;
    (gdb)
    11 for(int i = s; i <= e; i++)
    (gdb)
    13 result += i;
    (gdb) until 14
    Sum (s=1, e=100) at mycmd.c:16
    16 return result*flag;
    (gdb) p result
    $1 = 5050
    (gdb) p flag
    $2 = 0
    (gdb) set var flag=1 # 更改flag的值,确认是否是它的原因
    (gdb) p flag
    $3 = 1
    (gdb) n
    17 }
    (gdb) n
    main () at mycmd.c:25
    25 printf("running done, result is: [%d-%d]=%d\n", start, end,
    n);
    (gdb) n
    running done, result is: [1-100]=5050 # 是它的原因
    26 return 0;

    4.3 条件断点

    4.3.1 添加条件断点
    (gdb) l main
    11
    12 return result;
    13 }
    14
    15 int main()
    16 {
    17 int start = 1;
    18 int end = 100;
    19 printf("I will begin\n");
    20 int n = Sum(start, end);
    (gdb) b 20
    Breakpoint 1 at 0x11c3: file mycmd.c, line 20.
    (gdb) r
    Starting program: /home/whb/test/test/mycmd
    I will beginBreakpoint 1, main () at mycmd.c:20
    20 int n = Sum(start, end);
    (gdb) s
    Sum (s=32767, e=-7136) at mycmd.c:5
    5 {
    (gdb) n
    6 int result = 0;
    (gdb) n
    7 for(int i = s; i <= e; i++)
    (gdb) n
    9 result += i;
    (gdb) display i
    1: i = 1
    (gdb) n
    7 for(int i = s; i <= e; i++)
    1: i = 1
    (gdb) n
    9 result += i;
    1: i = 2
    (gdb) n
    7 for(int i = s; i <= e; i++)
    1: i = 2
    (gdb) n
    9 result += i;
    1: i = 3
    (gdb)
    7 for(int i = s; i <= e; i++)
    1: i = 3
    (gdb) info b
    Num Type Disp Enb Address What
    1 breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20
    breakpoint already hit 1 time
    (gdb) b 9 if i == 30 // 9是⾏号,表⽰新增断点的位置
    Breakpoint 2 at 0x555555555186: file mycmd.c, line 9.
    (gdb) info b
    Num Type Disp Enb Address What
    1 breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20breakpoint already hit 1 time
    2 breakpoint keep y 0x0000555555555186 in Sum at mycmd.c:9
    stop only if i == 30
    (gdb) finish
    Run till exit from #0 Sum (s=1, e=100) at mycmd.c:7
    Breakpoint 2, Sum (s=1, e=100) at mycmd.c:9
    9 result += i;
    1: i = 30
    (gdb) finish
    Run till exit from #0 Sum (s=1, e=100) at mycmd.c:9
    0x00005555555551d2 in main () at mycmd.c:20
    20 int n = Sum(start, end);
    Value returned is $1 = 5050
    4.3.2 给已经存在的断点添加条件
    (gdb) l main
    11
    12 return result;
    13 }
    14
    15 int main()
    16 {
    17 int start = 1;
    18 int end = 100;
    19 printf("I will begin\n");
    20 int n = Sum(start, end);
    (gdb) b 20
    Breakpoint 1 at 0x11c3: file mycmd.c, line 20.
    (gdb) r
    Starting program: /home/whb/test/test/mycmd
    I will begin
    Breakpoint 1, main () at mycmd.c:20
    20 int n = Sum(start, end);
    (gdb) s
    Sum (s=32767, e=-7136) at mycmd.c:5
    5 {
    (gdb) n
    6 int result = 0;
    (gdb) n
    7 for(int i = s; i <= e; i++)
    (gdb) n
    9 result += i;
    (gdb)
    7 for(int i = s; i <= e; i++)
    (gdb)
    9 result += i;
    (gdb)
    7 for(int i = s; i <= e; i++)
    (gdb)
    9 result += i;
    (gdb)
    7 for(int i = s; i <= e; i++)
    (gdb) b 9 // 我们在第9⾏新增⼀个断点,⽤来开始测试
    Breakpoint 2 at 0x555555555186: file mycmd.c, line 9.
    (gdb) info b
    Num Type Disp Enb Address What
    1 breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20breakpoint already hit 1 time
    2 breakpoint keep y 0x0000555555555186 in Sum at mycmd.c:9
    (gdb) n
    Breakpoint 2, Sum (s=1, e=100) at mycmd.c:9
    9 result += i;
    (gdb) n
    7 for(int i = s; i <= e; i++)
    (gdb) n
    Breakpoint 2, Sum (s=1, e=100) at mycmd.c:9
    9 result += i;
    (gdb) condition 2 i==30 // 给2号断点,新增条件i==30
    (gdb) info b
    Num Type Disp Enb Address What
    1 breakpoint keep y 0x00005555555551c3 in main at mycmd.c:20
    breakpoint already hit 1 time
    2 breakpoint keep y 0x0000555555555186 in Sum at mycmd.c:9
    stop only if i==30
    breakpoint already hit 2 times
    (gdb) n
    7 for(int i = s; i <= e; i++)
    (gdb) n
    9 result += i;
    (gdb) c
    Continuing.
    Breakpoint 2, Sum (s=1, e=100) at mycmd.c:9
    9 result += i;
    (gdb) p i
    $1 = 30
    (gdb) p result
    $2 = 435

    http://www.dtcms.com/a/582806.html

    相关文章:

  1. 神经流形:大脑功能几何基础的革命性视角
  2. 杭州做网站外包公司网站建设实训报告总结
  3. 高新区建设局网站网站建设与开发试卷
  4. 测试跟踪步骤描述用例交互优化,MeterSphere开源持续测试工具v2.10.26 LTS版本发布
  5. CSMA(aloha)
  6. 衡水做网站优化黄页网址大全免费
  7. 苍穹外卖 —— Spring Cache和购物车功能开发
  8. 建设网站毕业设计河南城乡建设厅网站证书查询
  9. 留言网站模板沈阳百度seo代理
  10. top域名的网站打不开平台软件
  11. 新开传奇手游网站大全jn建站系统官网
  12. 【AI安全】提示词注入
  13. 两个人做类似的梦 网站咨询类网站建设方案书
  14. 企业年报详情查询API——在线查询企业年报信息的可靠工具
  15. StarGAN标签是怎么传给神经网络的?作为数据中的一个或几个维度吗?
  16. 重庆忠县网站建设公司哪家专业移动互联网开发考研方向
  17. 基于图扑自研 HT 搭建的园区元宇宙可视化管理平台
  18. wordpress dux 下载一键优化清理神器
  19. 北京网站排名优化公司美工做任务网站
  20. 广州企业网站建设公司哪家好东莞网站推广多少钱
  21. 【Go】--log模块的使用
  22. 交互式参数控制面板:Panel与Bokeh Server深度解析
  23. Java基础——递归思想
  24. 美术馆网站的建设流程新浪网站制作
  25. 中国投诉网站做袜子机器多少钱一台重庆知名网站
  26. Rust 练习册 :Luhn From与From trait
  27. 服务器网站托管企业文化的重要性
  28. NumPy -数组创建
  29. 做网站方案怎么写合肥瑶海区寒假兼职工网站建设
  30. 学习RT-thread(事件集)