zoukankan      html  css  js  c++  java
  • gdb调试程序

    编写test2.c

    image

    编译成可执行文件

    gcc test2.c -g -o test2
    gdb test2

    进入gdb调试

    run命令

    run命令格式

    run <arg1...argn>

    其中run可以简写成r,gdb中大部分指令可以简写。

    在gdb中执行

    run lvyahui blog

    可以看到输出

    image

    再次运行run可以不需要再传递参数,它会使用最后一次调用run命令传递的参数

    image

    可以看到默认参数

    image

    可以再次执行带参数的run或者使用set agrs 修改默认参数

    image

    断点

    设置断点

    break <line-number>

    可以在vim编辑器中查看行号或者通过list/l指令查看行号

    image

    编辑代码文件test1.c

    image

    编译好test1

    gcc test1.c -g -o test1
    gdb test1

    进入gdb环境

    先查看代码,然后设置一个断点,再run执行,让后continue继续执行

    image

    在方法前添加断点

    break可以直接在方法前添加短点

    break fun_name

    image

    在此调试执行

    image

    删除断点

    下面看怎么删除之前设置的短点

    delete breakpoint <point-number> #删除指定断点
    #或者
    delete breakpoints  #删除所有断点

    其中 delete可以简写成d

    image

    另外clear命令也可以用来清除断点

    按表达式设置断点

    break <line number> if expression

    image

    按照上面的方法步骤设置断点,发现失败了,提示No symbol var in current context

    起初我以为是这样的设置需要在运行中设置,于是在13行设置断点,运行,当停在13行时,再在第15行设置一个条件断点,但

    最后发现问题依旧。显然问题不在这里,后来上网查了下,在编译时加上一个-gstabs+选项

    gcc -g -gstabs+ -c test1.c
    gcc test1.o -o test1

    再次进入gdb 调试

    发现就可以设置这个条件断点了

    image

    可以使用readelf看两次不同方法编译生成的.o文件的符号表有所不同。

    run执行下看看

    但是执行发现断点没有起作用

    image

    虽然不知道为什么,但显然之前是因为编译器做了编译优化,但我明明没有加任何-OX选项啊。后来把i==50换成i>=50,发现可以停下来了。

    image

    真是郁闷,i怎么会是这个值呢?

    如果是多文件程序,break还可以指定文件添加断点,格式如下

    break <filename:line-number>
    break <filename:fun-name>
    #例如
    break test1.c:15
    break test1.c:main

    禁止和启用断点

    格式

    disable/enable breakpoint num

    image

    观察点

    观察点也可以起到断点的作用

    编辑test3.c文件

    #include <stdio.h>
    
    int sum(int a){
        int i,res = 0;
        for(i=0;i < a;i++){
            res += i;
        }
        return res;
    }
    int main(void){
        int a = 10;
        int asum = sum(a);
        printf("asum is %d 
    ",asum);
        return 0;
    }

    编译

    gcc -g -gstabs+ -Wall test3.c -o test3

    watch 命令需要在运行程序后使用看,所以我们要先加一个断点让程序停下来

    image

    将断点删除,继续执行

    image

    查看运行数据

    在运行时常常使用print命令来查看数据,再次之前,需要先知道如何单步执行,进入函数,运行到下一个断点

    • next--执行一行源代码但不进入函数内部。
    • step--执行一行源代码而且进入函数内部。
    • continue -- 执行到下一暂停点或程序结束。

    再次调试test1程序

    image

    print的格式

    print <expression>
    #或者
    p <expression>

    其中expression可以是各种形式

    表达式

    p (i-6)*3+result

    函数调用

    p func(5)

    数组

    p *arr_name@arr_length

    编写test4.c

    #include <stdio.h>
    #include <string.h>
    
    int main(void){
        int arr[] = {1,2,3,4,5};
        int len = 4,i;
        int * arr2 = (int *) malloc(len * sizeof(int));
        for(i=0;i<len;i++){
            arr2[i]= i*2;
        }
        free(arr2);
        return 0;
    }

    进入gdb调试

    image

    自动显示变量

    display/fmt expr

    image

    控制格式的字符更printf的非常相似,在此不做赘述

    以上是个人总结的gdb的一些基础内容,更多内容会在后续博客中提及

  • 相关阅读:
    课程作业02
    课后作业01
    大道至简第一章伪代码
    《大道至简》读后感
    Codeforces 959 F. Mahmoud and Ehab and yet another xor task
    Codeforces 992 E. Nastya and King-Shamans
    Codeforces 835 F. Roads in the Kingdom
    Codeforces 980 D. Perfect Groups
    洛谷 P4315 月下“毛景树”
    JDOJ 1234: VIJOS-P1052 高斯消元
  • 原文地址:https://www.cnblogs.com/lvyahui/p/4782948.html
Copyright © 2011-2022 走看看