linux程序调试过程分析

1、gdb调试过程:
介绍:gdb不仅可以用来调试分析和解决实际问题,也可以用来学习程序运行的过程;
gdb的实现是靠ptrace,让被调试的程序作为gdb的子进程,有的通过gdb fork生成,
有的通过gdb attach收养,因此被调试子程序的所有信号和状态都可以被父进程监听和控制;

1)判断一个程序(可执行文件)是否带有调试信息:
    gdb helloworld    // helloworld表示要调试的可执行文件
    如果出现no debugging symbols found表示该程序没有调试信息;

2)编译生成带调试信息的程序:
    gcc -g            // 编译时加上-g参数即可保留程序中的调试信息

3)开始调试:
    gdb helloworld
    然后就是用各种gdb命令来协助调试;
    如run, next, step,break, bt, set args, show args, watch ...

2、core文件调试过程:
介绍:程序因为异常或bug造成crash可以产生core文件,通常core文件包含了程序运行时内存、
寄存器状态、堆栈指针、内存管理信息以及函数调用堆栈信息。core就是程序当前工作状态存储生成的一个文件,
通过工具分析这个文件,可以定位到程序异常退出的时候对应的堆栈调用等信息,找出问题点并解决。

1)查看coredump是否开启:
    ulimit -c
    如果为0表示coredump被关闭,通过如下设置开启:
    ulimit -c unlimited
    
    插一句:在windows系统cygwin下使能coredump还需要如下一步:
    export CYGWIN="$CYGWIN error_start=dumper.exe -d %1 %2" // 添加到.bashrc或当前shell下运行

2)生成core文件:
    ./helloworld    // 执行helloworld程序,如果程序异常crash就会在当前目录生成helloworld.core文件

3)利用core文件调试:
    gdb helloworld helloworld.core
    然后就可以用gdb的命令来查看和分析问题,常用的如bt来查看堆栈信息;

3、未涉及内容:
1)gdb具体命令的使用和操作方法;
2)gdb如何调试已运行的程序?gdb attach命令到已经运行的程序pid,即把运行程序pid收养到gdb进程下面;
3)已运行的程序没有调试信息,怎么调试?用同样的代码编译一份带调试信息的程序,
然后gdb file命令去读取重新编译好的程序中的调试的信息;

4、gdb命令使用:
gdb命令很多,学习时自己尝试运行一遍加深理解;

1)查看设置的断点:
    info b                               // 或info breakpoints
2)设置断点:
    a)b line                          // 如b 9
    b)b file:line                    // 如b test.c:9
    c)b line if reg                 // 如b 9 if a==10
    d)condition 3 a==20      // 修改断点属性,修改3号断点的条件为a==20 
    e)b function                   // 对所有定义的函数名称中包含function的函数设置断点
    f)rbreak file:.                 // 规则断点,对文件file中所有定义的函数设置断点
    g)rbreak file:print          // 规则断点,对文件file中所有定义的函数名称中包含print的函数设置断点
    h)tbreak 10                      // 临时断点,只会跑1次,后面就会失效
    i)ignore 1 30                    // 修改断点属性,修改1号断点忽略前面调用的30次
    j)watch var                      // 添加观察点,当变量var值发生改变时暂停并打印前后变化值,需要先运行才能添加
    k)rwatch var                    // 添加观测点,当变量var被读取时(read)暂停
    l)awatch var                    // 添加观测点,当变量var被读或写时(access)暂停
3)开关断点:
    a)disable                         // 关掉所有断点
    b)disable bnum               // 关掉断点号为bnum的断点
    c)enable                          // 开启所有断点
    d)enable bnum                // 开启断点号为bnum的断点
4)清除断点:
    a)clear                             // 清除所有breakpoints
    b)clear function               // 清除所有函数名为function的断点
    c)clear file:function          // 清除文件file中所有函数名为function的断点
    d)clear line                      // 清除行号line对应的断点
    e)clear file:function:line   // 清除文件file中函数function中行号line对应的断点
    f)delete                            // 清除所有breakpoints, watchpoints, catchpoints
    g)delete bnum                 // 清除断点号为bnum的断点
5)查看变量:
    a)print var 或 p var          // 查看变量var的值
    b)p point                          // 查看指针point的地址
    c)p *point                         // 查看指针point指向的内容
    d)p *point@10                 // 查看指针point指向的10组内容,如打印数组中的数据
    e)p $                                // $表示上一个变量,这里可以打印上一个变量的值
    f)p *$.next                        // 如果上一个变量是链表指针并且有next成员指针,可以用来打印next指向的内容
    g)set $i=0                        // 定义环境变量$i为0
       p array[$i]                       // 打印数组array[0]的数据
       p array[$i++]                   // 打印数组array[0]的数据,并且环境变量$i++累加为1
6)按格式查看变量:
    p/[f] var                              // 按格式查看,如p/x var,按十六进制查看变量var的值

    格式f:
        x 按十六进制格式显示变量
        d 按十进制格式显示变量
        u 按十六进制格式显示无符号整型
        o 按八进制格式显示变量
        t 按二进制格式显示变量
        a 按十六进制格式显示变量
        c 按字符格式显示变量
        f 按浮点数格式显示变量
7)查看内存:
    x/[n][f][u] addr

    n表示内存单元长度,默认为1
    f表示打印格式,即x,d,u,o,t,a,c,f
    u表示打印的单元类型:
        b:字节,
        h:半字,2字节
        w:字,4字节
        g: 8字节
8)自动显示变量内容
    a)display var                    // 添加变量var自动显示,当运行到任意断点暂停时会自动打印变量的值
    b)info display                   // 查看已经添加的自动显示的变量
    c)disable display dnum    // 禁用第dnum号自动显示变量
    d)enable display dnum    // 使能第dnum号自动显示变量
    e)delete display dnum     // 删除第dnum号自动显示变量
9)查看寄存器:
    info r                                  // 或info register
10)执行程序相关命令:
    a)run                               // 运行程序
    b)n [num]                        // 执行下一条或下几条语句,一般用在断点暂停后
    c)s                                   // 单步进入,如果是函数调用则可以进入函数,否则与n命令功能相同
        show step-mode            // 查看单步模式,如果遇到没有调试信息的函数是否跳过
        set step-mode on/off      // 设置不跳过/跳过,当不跳过时进入了函数后可通过finish跳出
    d)si                                  // 执行下一条机器指令
    e)c [num]                         // 继续运行直到下一次或下几次断点发生
    f)u line                             // 继续运行到指定行,相当于tb line再c,即添加临时断点再继续运行
    g)skip function func         // 跳过函数func的执行,这样s单步就会进入函数func了
    h)skip file file.c                // 跳过文件file.c中的所有函数,这样文件file.c中所有函数都不会进入了
        info skip                         // 查看所有添加的skip
        skip disable [snum]        // 禁用snum号对应的或所有skip
        skip enable [snum]         // 使能snum号对应的或所有skip
        skip delete [snum]          // 删除snum号对应的或所有skip
11)查看源码:
    a)l                                   // 或list,默认查看10行代码,需要执行l可以查看下面10行
    b)l +/-                              // 查看下一页或上一页的10行代码
    c)l line                             // 查看行line附近的10行代码,一般是line前面5行,后面5行
    d)set listsize 20               // 设置list一页可以显示的代码行数
    e)show listsize                // 查看list一页可以显示的代码行数,默认是10行
    f)l first,last                       // 查看first到last行之间的代码
    g)l file:line                       // 查看文件file中line行附近的代码
    h)l function                      // 查看函数function开始的代码
    i)l file:function                 // 查看文件file中函数function开始的代码
    j)l file:first,file:last            // 查看文件file中first到last行之间的代码
    k)dir path                        // 指定源码路径,如果需要查看的文件不在当前目录,则可以添加搜索路径
12)编辑源码:
    a)edit line                       // 编辑第line行开始的源码
    b)edit function                // 编辑函数function开始的代码
    c)edit file:line                  // 编辑文件file中函数line行附近的代码
    d)edit file:function          // 编辑文件file中函数function开始的代码
13)执行shell命令:
    shell cmd                             // 需在命令前加上shell
      如: (gdb) shell pwd            // 查看当前工作目录
            (gdb) shell ls -l             // list当前目录
            (gdb) shell vim file.c    // 用vim打开文件file.c
14)高级应用:
    info thread                           // 查看线程信息
    ...

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值