gdb调试大全

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
    Copyright (C) 2020 Free Software Foundation, Inc.
    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
      Copyright (C) 2020 Free Software Foundation, Inc.
      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()
    18	{
    19	    printf("%s\n", __func__);
    20	    printf("go to home\n");
    (gdb) 
    21	    sleep(100);
    22	}
    23	
    24	void pthread_handler(void *value)
    25	{
    26	    char *name = (char *)value;
    27	
    28	    if (0 == strcmp("cat", name)) 
    29	        animal_active_handle(name, active_func);    
    30	
    (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删除断点)

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
FreeRTOS是一个开源的实时操作系统,它提供了一套用嵌入式系统的任务调度和管理机制。GDB(GNU Debugger)是一个功能强大的调试工具,可以用于调试C/C++程序。在使用FreeRTOS进行开发时,可以结合GDB进行调试。 要在FreeRTOS中使用GDB进行调试,需要进行以下几个步骤: 1. 配置编译器:首先,需要确保你的编译器支持GDB调试功能。常用的编译器如GCC和Keil都支持GDB调试。 2. 编译选项:在编译FreeRTOS应用程序时,需要添加一些编译选项以支持GDB调试。例如,在GCC中,可以使用"-g"选项来生成调试信息。 3. 连接器脚本:在链接应用程序时,需要使用连接器脚本来指定调试信息的位置。连接器脚本可以告诉GDB在哪里找到符号表和调试信息。 4. 启动GDB调试:在编译和链接完成后,可以使用GDB启动调试会话。可以通过命令行输入"gdb"命令来启动GDB,并使用"target remote"命令连接到目标设备。 5. 设置断点:在GDB中,可以使用"break"命令设置断点。可以设置函数断点、行号断点或地址断点等。 6. 执行调试:一旦设置好断点,可以使用GDB的调试命令来执行程序。可以使用"run"命令来运行程序,使用"step"命令逐行执行,使用"next"命令执行下一行,使用"continue"命令继续执行等。 7. 查看变量:在调试过程中,可以使用GDB的"print"命令来查看变量的值。可以使用"info locals"命令查看局部变量,使用"info global"命令查看全局变量等。 8. 结束调试:当调试完成后,可以使用GDB的"quit"命令退出调试会话。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值