官网手册:用户手册
动机:学这个就是为了找到Segment Default报错的位置
根据linux的版本或者是mac,有的可能不是gdb而是lldb,不过这两比较类似,可以类比。
一. 基础操作
-
安装时,在终端输入
sudo apt-get install gdb
如果需要特定版本,去官网下载源码。Clion中自带gdb,和这个另外安装的是分开的。 -
使用gdb调试之前:在CMakeLists中使用Debug模式
set(CMAKE_BUILD_TYPE Debug)
,或者在编译选项中加入-g,set(CMAKE_CXX_FLAGS "-g")
,之后再进行编译生成可执行文件。 -
对一个可执行文件进入gdb模式:
· 直接用gdb filename
装载这个文件
· 先输入gdb
进入调试模式,再用file filename
的命令装载该文件 -
运行gdb,输入
run/r
。执行当前语句用next/n
,继续运行程序直到遇到端点continue/c
,退出使用quit
-
进入gdb模式之后,之前在终端使用的指令就不起作用了,比如想查看当前文件夹下的文件,想用
ls
就会报错undefined command,这时可以输入shell ls
,在平时的终端指令前加一个shell就好了。 -
如果想查询相关指令,可以去用户手册中查找,或者输入
man gdb
查看介绍,如果想查看具体的命令怎么用,可以输入help b
,这里的b就是一个指令名,然后就会显示出break的具体用法。
二. 文件显示
如果用ssh这种远程使用,没法用IDE直接查看代码,就可以用list
功能,可以显示代码以及代码对应的行数;set listsize 20
就是设置一次可以显示20行代码。
list命令可以指定行号,函数:
(gdb) l 24
(gdb) l main
还可以指定向前或向后打印:
(gdb) l -
(gdb) l +
还可以指定范围:
(gdb) l 1,10
如果想查看某一行代码对应的内存地址,可以使用:
info line 19
三. 常用指令
A. 参数设置
在装载了要调试的二进制文件后,如果运行程序需要给一些参数,比如配置文件,数据集文件夹等等,在gdb中就要使用:
set args config.yaml ~/dataset/dirName
如果要查看参数:
show args
或者print args
B. 断点设置
在Clion设置的断点在gdb是可以看到的,但是反过来不行。
常用的断点有三种形式:行号、函数名、条件
break/b lineNum
break/b functionName
在函数入口设置断点
break/b test.cpp:23 if b==0
多文件时要写上文件名,注意变量要在生命周期内
如果想查看断点信息:
info breakpoint
如果需要进出函数内部:step/s
注意如果工程包含了函数的源码,就可以进去,但如果只是包含库没有源码就进不去。
从函数内部退出:finish
C. 查看&设置变量
直接显示变量的值:print 变量名
设置变量这里就体现出了一些优势,在IDE中修改后需要重新编译,这里直接改完就可以继续Debug:set var 变量名=新值
四. 调试多线程程序
由于程序中用到了多线程的函数库 #include <pthread> 所以在终端编译的时候要加上对应的指令 gcc -g demo.cpp -o demo -lpthread
在终端:
查看线程的命令:ps -aL | grep demo
查看主线程和子线程的关系(树形图):pstree -p 主线程id
在gdb中:
查看当前线程: info threads
进入某一个线程:thread 线程号
如果只运行当前线程,即把其他线程挂起:set scheduler-locking on
默认情况是运行全部线程,也可以手动设置:set scheduler-locking off
指定某个线程执行命令:thread apply 线程编号 gdb命令
让所有线程都执行同一个命令:thread apply all gdb命令