GDB调试

gdb基本命令汇总

command
file <文件名> 加载被调试的可执行程序文件
run 单步执行,运行程序,停在第一执行语句 如果可执行程序需要传参,可写在run后面
list 查看源代码,简写l
set 设置变量的值
next 单步调试(不进入的单步执行,函数直接执行),简写n
step 单步调试(跳入自定义函数内部执行,使用finish退出该函数的调用函数),简写s
backtrace 查看函数的调用的栈和层级关系,简写bt
frame 切换函数的栈帧,简写f
info 查看函数内部局部变量的数值,简写i
finish 结束当前函数,返回到函数调用点
continue 继续运行,简写c
print 打印值及地址,简写p
quit 退出gdb,简写q
delete 删除断点

调试可执行文件

  • 文件是否可以被gdb调试,判断二进制文件编译时是否带有-g参数

    • 方法一:要调试C/C++的程序,首先在编译源代码时加上-g参数(如果没有-g参数编译程序会报 No debugging symbols found in )
    • 方法二:读取可执行程序头部信息( 看是否含有debug调试信息 )readelf -S test_out | grep debug
      [28] .debug_aranges PROGBITS 0000000000000000 00003039
      [29] .debug_info PROGBITS 0000000000000000 00003069
      [30] .debug_abbrev PROGBITS 0000000000000000 00003378
      [31] .debug_line PROGBITS 0000000000000000 00003444
      [32] .debug_str PROGBITS 0000000000000000 00003556

调试core文件

core dump:core的意思是内存,dump意思是扔出来(段错误)。开发和使用Unix程序时会出现程序down掉,有时会提示( core dumped ),通过gdb分析core文件,方便我们快速定位问题

  • 如何生成core文件

    首先在当前终端输入ulimit -c,若为0,则不会生成core文件;若不为0,则会生成最大为这个数的core文件( 数值可能会小了 );我们需要必须让core文件生成,设置core大小为无限 ulimit -c unlimited

  • 如何指定存储core文件

    %t:core dump产生的时间

    %e:产生core dump的程序名称

    %p:产生core dump的进程ID

    • 方法一: 终端设置临时修改

      root模式下修改/proc/sys/kernel/core_pattern文件 ,/home/cjj/gdb-test/coredump/为存放core文件的目录

      cjj@ubuntu:~/gdb-test$ su Password:
      root@ubuntu:/home/cjj/gdb-test# echo /home/cjj/gdb-test/coredump/coredump.%t.%e.%p> /proc/sys/kernel/core_pattern

    • 方法二: 系统配置文件设置

      修改linux内核配置文件==/etc/sysctl.conf==,添加如下:

      kernel.core_pattern = /home/cjj/gdb-test/coredump/coredump.%t.%e.%p

      kernel.core_uses_pid = 1

      使能配置文件: sysctl -p /etc/sysctl.conf

  • 如何调试core文件,定位问题

    • 方法一: gdb <可执行文件> <core文件>
    cjj@ubuntu:~/gdb-test/coredump$ gdb ../test_out coredump.test_out.37006
    GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.
    Type "show copying" and "show warranty" for details.
    This GDB was configured as "x86_64-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
        <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from ../test_out...
    [New LWP 37006]
    Core was generated by `./test_out'.
    Program terminated with signal SIGSEGV, Segmentation fault.
    #0  __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:190
    190	../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: No such file or directory.
    (gdb) 
    (gdb) bt
    #0  __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:190
    #1  0x00005614d22c419f in main () at test.c:10
    (gdb) 
      
    • 方法二:gdb <可执行文件>

      cjj@ubuntu:~/gdb-test/coredump$ gdb ../test_out 
      GNU gdb (Ubuntu 9.1-0ubuntu1) 9.1
      License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
      This is free software: you are free to change and redistribute it.
      There is NO WARRANTY, to the extent permitted by law.
      Type "show copying" and "show warranty" for details.
      This GDB was configured as "x86_64-linux-gnu".
      Type "show configuration" for configuration details.
      For bug reporting instructions, please see:
      <http://www.gnu.org/software/gdb/bugs/>.
      Find the GDB manual and other documentation resources online at:
          <http://www.gnu.org/software/gdb/documentation/>.
      For help, type "help".
      Type "apropos word" to search for commands related to "word"...
      Reading symbols from ../test_out...
      (gdb) core-file coredump.test_out.37006 
      [New LWP 37006]
      Core was generated by `./test_out'.
      Program terminated with signal SIGSEGV, Segmentation fault.
      #0  __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:190
      190	../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S: No such file or directory.
      (gdb) bt
      #0  __memset_avx2_unaligned_erms () at ../sysdeps/x86_64/multiarch/memset-vec-unaligned-erms.S:190
      #1  0x00005614d22c419f in main () at test.c:10
      (gdb) 
      

    注:gdb内部执行bt(back trance查看函数的调用的栈帧和层级关系)后,打印段错误产生原因memset和产生位置test.c:10

gdb断点调试

在开始断点调试前,我有三个疑问,我们带着这三个疑问展开下面的学习:

1. 什么是设置断点调试?

2. 设置断点调试,在实际开发中有什么作用?

3. 如何设置断点调试?

  • 1. 什么是设置断点调试?

    通过设置代码行、函数名、条件语句、指定例程入口位置暂停,然后分析变量值和堆栈信息。

    • 单文件断点设置

      command
      break line-number 使程序巧好在给定行之前停止
      break function-name 使程序恰好在进入给定函数之前停止
      break line or function if condition 如何condition条件为真,则程序会到达指定line或function之前停止
      break routine 在指定例程入口处设置断点
    • 多文件断点设置

      command
      break file-name:line-number 使程序巧好在给定行之前停止
  • 2. 设置断点调试,在实际开发中有什么作用?

    16	//================用户传入方法======================
    17	void active_func()
    19	    printf("%s\n", __func__);
    20	    printf("go to home\n");
    (gdb) 
    21	    sleep(100);
    24	void pthread_handler(void *value)
    26	    char *name = (char *)value;
    28	    if (0 == strcmp("cat", name)) 
    29	        animal_active_handle(name, active_func);    
    (gdb) b 21
    Breakpoint 1 at 0x12aa: file test.c, line 21.
    (gdb) run
    Starting program: /home/cjj/gdb-test/test_out 
    [Thread debugging using libthread_db enabled]
    Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
    [New Thread 0x7ffff7d96700 (LWP 40777)]
    #########name=cat##########
    active_func
    go to home
    [New Thread 0x7ffff7595700 (LWP 40778)]
    [140737343215360]dog
    [New Thread 0x7ffff6d94700 (LWP 40779)]
    [Switching to Thread 0x7ffff7d96700 (LWP 40777)]
    Thread 2 "test_out" hit Breakpoint 1, active_func () at test.c:21
    21	    sleep(100);
    (gdb) bt
    #0  active_func () at test.c:21
    #1  0x000055555555527b in animal_active_handle (name=0x555555556041 "cat", 
        func=0x55555555528a <active_func>) at test.c:12
    #2  0x00005555555552f9 in pthread_handler (value=0x555555556041) at test.c:29
    #3  0x00007ffff7f94609 in start_thread (arg=<optimized out>) at pthread_create.c:477
    #4  0x00007ffff7eb9163 in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
    (gdb) info b
    Num     Type           Disp Enb Address            What
    1       breakpoint     keep y   0x00005555555552aa in active_func at test.c:21
    	breakpoint already hit 1 time
    (gdb) info frame
    Stack level 0, frame at 0x7ffff7d95eb0:
     rip = 0x5555555552aa in active_func (test.c:21); saved rip = 0x55555555527b
     called by frame at 0x7ffff7d95ed0
     source language c.
     Arglist at 0x7ffff7d95e98, args: 
     Locals at 0x7ffff7d95e98, Previous frame's sp is 0x7ffff7d95eb0
     Saved registers:
      rbp at 0x7ffff7d95ea0, rip at 0x7ffff7d95ea8
    (gdb) info threads
      Id   Target Id                                    Frame 
      1    Thread 0x7ffff7d97740 (LWP 40773) "test_out" clone ()
        at ../sysdeps/unix/sysv/linux/x86_64/clone.S:78
    * 2    Thread 0x7ffff7d96700 (LWP 40777) "test_out" active_func () at test.c:21
      3    Thread 0x7ffff7595700 (LWP 40778) "test_out" 0x00007ffff7e7726f in __GI___clock_nanosleep (
        clock_id=clock_id@entry=0, flags=flags@entry=0, req=req@entry=0x7ffff7594e90, 
        rem=rem@entry=0x7ffff7594e90) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
      4    Thread 0x7ffff6d94700 (LWP 40779) "test_out" clone ()
        at ../sysdeps/unix/sysv/linux/x86_64/clone.S:78
    (gdb) 
    

    注:当代码量比较大,并且代码的调用比较复杂时候,可以在某个函数内添加断点,然后根据bt指令打印出函数调用的堆栈信息,可以清晰的知道这个函数是被谁调用的,方便分析函数的调用关系

  • 3. 如何设置断点调试?

    断点调试常用指令:r(run执行程序)、b(break trance设置断点)、n(next单步调试,运行到下一个断点)、p(print打印变量值)、l(list查看源码)、s(step单步调试,进入子函数内部)、d(delete删除断点)

    设置断点后,可以在断点处查看堆栈信息及变量值,可以一步一步的看到变量和堆栈信息的变化,

文章目录GDB调试gdb基本命令汇总调试可执行文件调试core文件gdb断点调试GDB调试gdb基本命令汇总commandfile &lt;文件名&gt;加载被调试的可执行程序文件run单步执行,运行程序,停在第一执行语句如果可执行程序需要传参,可写在run后面list查看源代码,简写lset设置变量的值next单步调试(不进入的单步执行,函数直接执行),简写nstep单步调试(跳入自定义函数内部执行,使用finish退出该函数的调用函数) make ARCH=um -j8 来编译 ./ linux --help VFS: Mounted root (ext3 filesystem) readonly on device 98:0. 创建 dev 目录 进入中端后执行如下命令: INSTALL_MOD_PATH= ./virtual/uml/UserMode Linux -HOWTO.txt There are currently five transport types ava
关注公众号【高性能架构探索】,回复【pdf】,免费获取计算机经典资料 在上篇文章中,我们分析了线上coredump产生的原因,其中用到了coredump分析工具 gdb ,这几天一直有读者在问,能不能写一篇关于 gdb调试 方面的文章,今天借助此文,分享一些工作中的调试经验,希望能够帮到大家。 在我的工作经历中,前几年在Windows上进行开发,使用Visual Studio进行调试,简直是利器,各种断点等用鼠标点点点就能设置;大概从12年开始转 Linux 开发了,所以调试都是基于 GDB 的。本来这篇文章.
通过 gdb调试 我们可以监控程序执行的每一个细节,包括变量的值、函数的调用过程、内存中数据、线程的调度等,从而发现隐藏的错误或者低效的代码,程序的调试过程主要有:单步执行,跳入函数,跳出函数,设置断点,设置观察点,查看变量。 本文将主要介绍 linux 下的 gdb调试 工具常用的命令和具体的使用实例。 二、调试过程介绍 2.1 编译程序加参数时生成调试信息 -g 和 -g gdb 都是令 gcc 生成调试信息,但是它们也是有区别的