gdb的基本使用

oneNeko 于 2022-06-16 发布

GDB(GNU Debugger)UNIXUNIX-like下的调试工具。

启动调试

gdb需要程序保留有调试信息才能调试

检查调试信息

对于C/C++程序来说,需要在编译时加上-g参数保留调试信息。如

$ g++ helloworld.cc -o helloworld -g
$ gdb helloworld
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.1) 9.2
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 helloworld...
(gdb) 

否则会提示没有调试信息(No debugging symbols found in helloworld)

另一种检查是否有调试信息的方法,使用readlf查看段信息:

$ readelf -S helloworld|grep debug
[28] .debug_aranges    PROGBITS         0000000000000000  0000303b
[29] .debug_info       PROGBITS         0000000000000000  0000306b
[30] .debug_abbrev     PROGBITS         0000000000000000  00005d03
[31] .debug_line       PROGBITS         0000000000000000  0000634c
[32] .debug_str        PROGBITS         0000000000000000  0000673c

以调试方式运行程序

先运行gdb programname,进入gdb调试命令行,之后执行run [参数]启动程序

(gdb) run
Starting program: /home/helloworld 
hello world
[Inferior 1 (process 2128) exited normally]

调试core文件

当程序发生中断或崩溃时,可能会产生core文件,它能够很大程序帮助我们定位问题。但前提是系统没有限制core文件的产生。可以使用命令ulimit -c查看:

$ ulimit -c           #查询core文件大小限制
0                     #不会有core文件产生

$ ulimit -c unlimied  #表示不限制core文件大小
$ ulimit -c 10        #设置最大大小,单位为块,一块默认为512字节

调试命令:gdb [程序名] [core文件名]

调试已运行程序

使用attach [程序pid]或直接gdb [program name] [pid],如:

$ pidof helloworld
5611
$ gdb
(gdb) attach 5611

# 直接调试进程
$ gdb helloworld 5611

断点设置

设置断点可以让程序停在我们想要的地方,使用info breakpoints查看已设置的断点

设置断点

#break可以简写成b,单文件可省略文件名
#根据行号设置断点
#用法:break [文件名]:[行号] #在指定文件行号上设置断点,
(gdb) break helloworld.cc:7
(gdb) break 7
(gdb) b 7
 
#根据函数名设置断点
#用法:break [文件名]:[函数] #在指定文件函数上设置断点
(gdb) b main

#根据条件设置断点
#用法:break [文件名]:[行号] if [条件] #符合设置条件时停下,类似于condition
(gdb) b test if a==10

#condition
(gdb) condition 1 a==10 #a=10时在断点1停下

#对所有函数设置断点
#用法:rbreak [文件名]:[函数名regex]
(gdb) rbreak printNum*  #对以printNum开头的函数设置断点
(gdb) rbreak .          #对所有函数设置断点
(gdb) rbreak helloworld.cc:. #对helloworld.cc里的全部函数设置断点

#设置临时断点
#用法:tbreak [文件名]:[行号]
(gdb) tbreak helloworld.cc:10 #设置只生效一次断点

#跳过断点n次
#用法:ignore [break_id] [次数n]
(gdb) ignore 1 30

启用、禁用或清除断点

disable  #禁用所有断点
disable bnum #禁用标号为bnum的断点
enable  #启用所有断点
enable bnum #启用标号为bnum的断点
enable delete bnum  #启动标号为bnum的断点,并且在此之后删除该断点

clear   #删除当前行所有breakpoints
clear function  #删除函数名为function处的断点
clear filename:function #删除文件filename中函数function处的断点
clear lineNum #删除行号为lineNum处的断点
clear f:lename:lineNum #删除文件filename中行号为lineNum处的断点
delete  #删除所有breakpoints,watchpoints和catchpoints
delete bnum #删除断点号为bnum的断点

变量查看

document.body.style.setProperty('--background-color', '#7F583F')
document.body.style.getPropertyValue('--background-color').trim()
document.body.style.removeProperty('--background-color')
document.body.style = '--background-color:#7F583F;'

参考

GDB调试入门指南