在开发定位过程中,肯定会用到gdb去跟踪定位分析问题,下面是记录一些常用的命令,方便后续查找。

1:比如我要自己编译一个小程序,然后想用gdb去跟踪,

在GDB下调试一个小程序的基本步骤如下:

           1.编写源代码:

    // hello.c
    #include <stdio.h>
 
    int main() {
        printf("Hello, World!\n");
        return 0;
    }

  1.  

    2.编译源代码,生成可执行文件:想要能用gdb跟进去调试,就需要加上-g

    gcc -g hello.c -o hello

    如果里面有创建线程的,编译的时候需要加上-lpthread,如下:

    gcc -g hello.c -o hello -lpthread

     

    3.使用GDB调试程序:

    gdb hello

    4.在GDB环境中进行调试,例如设置断点、查看变量值等:

    (gdb) break main  # 设置断点在main函数处
    (gdb) run        # 运行程序
    (gdb) print i    # 查看变量i的值(如果程序中有int i;)
    (gdb) quit       # 退出GDB

    以上步骤可以帮助你使用GDB对一个简单的程序进行调试。

     

    5.调试core文件

    Core Dump:Core的意思是内存,Dump的意思是扔出来,堆出来(段错误)。开发和使用Unix程序时,有时程序莫名其妙的down了,却没有任何的提示(有时候会提示core dumped),这时候可以查看一下有没有形如core.进程号的文件生成,这个文件便是操作系统把程序down掉时的内存内容扔出来生成的, 它可以做为调试程序的参考,能够很大程序帮助我们定位问题。那怎么生成Core文件呢?
    生成Core方法

    产生coredump的条件,首先需要确认当前会话的ulimit –c,若为0,则不会产生对应的coredump,需要进行修改和设置。
    即便程序core dump了也不会有core文件留下。我们需要让core文件能够产生,设置core大小为无限:

    ulimit -c unlimited

    更改core dump生成路径

    因为core dump默认会生成在程序的工作目录,但是有些程序存在切换目录的情况,导致core dump生成的路径没有规律,

    所以最好是自己建立一个文件夹,存放生成的core文件。

    我建立一个 /data/coredump 文件夹,在根目录data里的coredump文件夹。
    ————————————————
    调用如下命令:
    echo /data/coredump/core.%e.%p> /proc/sys/kernel/core_pattern

    将更改core文件生成路径,自动放在这个/data/coredump文件夹里。

    %e表示程序名, %p表示进程id

     

    6、关于断点

    可以使用b+文件名+行号,或者指定函数名,可用if限定条件断点。
    使用info breakpoints列出所有断点,使用delete 1删除编号为1的断点。

    break test.c:6

    break test.c:6 if num>0

    b fucntionname
    

    6、关于源代码查看

    list first,last

    list  6, 20  

    显示代码6-20行

     

    7:关于调试多线程程序

    查看当前运行的进程
    ps -aux | grep main

    查看当前运行的轻量级进程
    ps -aL | grep -w main

    查看主线程和新线程的关系
    pstree -p 主线程id


    8:gdb进去怎么打印地址内容

    gdb调试时可以使用以下方式打印变量,

    • print
    • x
    • whatis
    • ptype
    • info



    命令作用
    x/s str 打印字符串str
    set print elements 0 打印不限制字符串长度/或不限制数组长度
    call printf("%s\n", xxx) 这是打印出的字符串不会含有多余的转义字、符
    printf("%s\n", xxx)  

     

     打印指针/结构体

    命令作用
    print ptr 查看该指针指向的类型及指针地址
    print *(struct xxx *)ptr 查看指向的结构体内容

     

    打印数组

    命令作用
    print *array@10 打印从数组开头连续10个元素的值
    print array[60]@10 打印第60~69个元素
    set print array-indexes on 打印数组元素时,同时打印数组下标
    *(float *)(addr)@num 打印地址值 将addr转换成float*类型,并打印num个值

    打印指定内存地址的值

    使用x命令来打印内存的值,格式为x/nfu addr,以f格式打印从addr开始的n个长度单元为u的内存值。

    • n:输出单元的个数
    • f : 输出格式,如x表示以16进制输出,o表示以8进制数处,默认x
    • u:一个单元的长度,b表示1byte,h表示2byte(half word),w表示4byte,g表示8byte(giant word)。
    命令作用
    x/8xb 16进制形式打印8byte
    x/8xw 16进制形式打印8个单字(word)
    x/10sg 字符串形式打印10个双字

     

    上面这个命令还是比较好用的,直接在gdb里面打印:

    x/32xg

     

    (gdb) info line demo_lock.c:13
    Line 13 of "demo_lock.c" starts at address 0xaaaaaaaa0a08 <process+44> and ends at 0xaaaaaaaa0a14

    (gdb) x/32xg 0xaaaaaaaa0a08
    0xaaaaaaaa0a08 <process+44>:    0x91006000d0000080      0xb000008097ffffa4

    .................................................................................................................................

    就这样连续的打

     

    link:

    https://blog.csdn.net/weixin_68063596/article/details/132342865     ---- 这个里面介绍的比较全面

    https://zhuanlan.zhihu.com/p/508160353     -----gdb进去,打印地址内容

     

     

posted on 2024-03-21 10:58  shiyuan310  阅读(5)  评论(0编辑  收藏  举报