• C程序调试与GDB入门


    1、Assert

    引用自<assert.h>的函数assert(int expression),当表达式的值为0则返回failed

    2、GDB

    gdb是GUN的提供在unix上的调试工具。

    安装sudo apt install gdb

    如果是windows,则寻找对应的exe安装即可,同时需要配置环境变量

    2.1 使用流程

    # 编译,得到executable程序
    # -g指令会列出行号、注释信息
    gcc -g -o executable one.c two.c other.c 
    
    # gdb调试
    gdb executable
    
    # 指定某行打断点,或者指定某个函数为断点
    break one:17
    break main
    
    #运行
    run [args]
    
    # 显示待验证的变量值,此后每次停下来都会显示这些变量值
    display var1
    display var2
    
    # 快进到下一个断点/或者运行到结尾
    continue
    
    # 退出
    quit
    

    2.2 断点和条件中断

    着重说一下断点的标识和查询。

    怎么打断点

    # 直接在函数上打断点
    break <function_name>
    
    # 作用在指定行上,如果是多文件,可以使用filename指定特定的源文件
    break <filename>:line_num
    

    断点信息查询以及断点的删除、禁用等

    # 查询全部的断点,显示信息的第一列是每一个断点id
    info breakpoints
    
    #删除断点
    delete break_id
    
    # 禁用断点
    disable break_id
    
    #重启被禁用的断点
    enable break_id
    
    #忽略断点times次
    #也就意味着,在运行到断点times次以后,断点会再次生效
    ignore break_id times
    

    条件中断

    条件中断,即满足指定条件才会触发中断的断点,某些时候这非常有用,譬如某些信号量达到预定值才会触发中断,如果Java中的异常中断一样。

    # 设置条件断点 
    break line_num if [expression]
    

    譬如,break swap if m > 100,需要注意只有在断点处m变量生效,该条件才会生效。

    对于已经设置的断点可以使用condition指定:

    # 给break_id断点设置中断条件
    condition break_id [expresion]
    
    # 取消中断条件,只要后面什么条件也不跟即可
    condition break_id
    

    2.3 常用的指令

    help-帮助指令
    
    run-运行
    
    quit-退出
    
    break-打断点,可以断某个行或者某个函数如`break main`
    
    next-下一行,简写`n`
    
    step-也是下一行,不同于next的是,如果某个行本身引用了函数,则会step into到该函数内部去,简写`s`
    
    finish-跳出当前函数/或者打到下一个断点
    
    continue,下一个断点或者运行到结尾,简写`c`
    
    display-跟踪打印某个变量的值
    
    print-一次打印当前状态下所指定变量的值
    
    detele-删除全部断点
    
    info breakpoint-全部断点信息
    
    clear-清楚断点,clear function,清楚函数断点
    
    until-类似于next,但是在循环中时,它可以一步到位直接到循环结束,而不像next一样执行每一次迭代
    
    list-列出当前行上下的代码,list function列出函数的代码
    

    2.4 一些补充——栈帧观察、监测点

    补充两点内容。

    我们知道系统会使用栈(Stack)数据结构存储调用函数,运行中的函数入栈,运行完毕则出栈。栈元素主要被包含函数地址、局部变量、参数名等。当我们需要了解程序的调用路径的时候,可以使用info stack等语句追踪函数运行轨迹。

    第二点涉及到观测点(watchpoint)或者说监测点。观测点设置后会被当作断点一样对待。与普通断点(breakpoint)不同的是,观测点主要关注一个或者多个被声明的变量,当这些变量变动或者这些变量被调用时,则触发【观测点】。

    1 调用栈查询

    当到达一个断点的时候,想查看此时的调用栈?

    # backtrace显示当前程序的调用栈,或者使用bt指令
    backtrace
    
    # 显示一个栈帧详情,frame_id就是bt查询结果的第一列数值
    frame [farme_id]
    

    当程序运行到某个函数时,该函数位于栈结构的顶部——即当前栈,可以使用info指令查询当前栈的详情:

    # 当前栈顶详情
    # 其中会有eip和ebp两个数值,eip表示下一个指令地址;ebp表示当前栈帧地址
    info frame
    
    # 查询当前栈帧的局部变量
    info locals
    
    # 查询当前栈帧的入参
    info args
    

    2 观测点

    首先需要注意的是,只有相应的变量对当前栈帧可见,才可以在这个时候定义该变量的观测点。

    有三种创建观测点的方法,侧重点各不相同,指令格式为watch [expresion]

    # 表达式内的变量都会被监测到
    #所以a、b的值有变动,就会触发观测点,此时暂时程序下来,如同断点触发一样
    watch a+b
    
    # b被读取即触发断点
    rwatch b
    
    # a或者b被读取、修改、参与计算都会触发断点
    awatch a+b
    

    一般情况下,使用watch指令足够了。

  • 相关阅读:
    APIO2020 粉刷墙壁
    上传文件超过1MB时,前端直接返回500,没有进入到上传方法
    mybatis xml 文件中 判断条件为时间,则不能做空字符串判断,否则会报错
    springcloud 多模块自动化部署 (Cloud Toolkit)
    @RequestBody Content type 'multipart/form-data;boundary=----WebKitFormBoundarybEyHr0FZTTOHW7Vq;charset=UTF-8' not supported
    读取视频时长
    zuul中使用Configuration注解后,过滤器无响应
    IDEA 2020.1 无法点击表名链接到数据源
    IDEA 常用插件
    转账到支付宝账户
  • 原文地址:https://www.cnblogs.com/Franken-Fran/p/gdb_use.html
Copyright © 2020-2023  润新知