GDB常用命令总结

GDB调试需要特别注意工作目录,否则可能断点命中不了!!

可以info break 看下address 是不是pending 

(gdb) info b
Num     Type           Disp Enb Address    What
1       breakpoint     keep y   <PENDING>  Depth_Analysis_Adapter.cpp:300

(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x00007f4973085a85 in Depth_Analysis_Adapter::TimeToFinish(uint32, uint32)
                                               at ./Depth_Analysis_Adapter.cpp:300

多线程下禁止线程切换:set scheduler-locking on

或指定线程断点

b location t tid   //b CConnect::UnBind(bool)if ( this == 0 ) t 77

如果循环次数很多,如何执行完当前的循环?(until)  

*指定程序直到退出当前循环体: (没搞明白用法)
(gdb) until 
或(gdb) u 
这里,发现需要把光标停止在循环的头部,然后输入u这样就自动执行全部的循环了。 

 *启动gdb,并且分屏显示源代码: 
$gdb -tui 
这样,使用了'-tui'选项,启动可以直接将屏幕分成两个部分,上面显示源代码,比用list方便多了。这时候使用上下方向键可以查看源代码,想要命令行使用上下键就用[Ctrl]n和[Ctrl]p. 

 gdb -p pid -tui

效果很完美

info 显示与该程序有关的各种信息 
info func 显示所有的函数名称。 


info break 显示当前断点清单,包括到达断点处的次数等。 


info breakpoints [N] 
info break [N]  带参数N的'info break'命令只显示由N指定的断点的信息。
info watchpoints [N]
显示所有的断点和观察点的设置表,有下列一些列
*Breakpoint Numbers*----断点号
*Type*----断点类型(断点或是观察点)
*Disposition*---显示断点的状态
*Enabled or Disabled*---使能或不使能。'y'表示使能,'n'表示不使能。
*Address*----地址,断点在你程序中的地址(内存地址)
*What*---地址,断点在你程序中的行号。
如果断点是条件断点,此命令还显示断点所需要的条件。


info files 显示被调试文件的详细信息。 
info local 显示当函数中的局部变量信息。 
info prog 显示被调试程序的执行状态。 
info var 显示所有的全局和静态变量名称。 

print EXPR 显示表达式 EXPR 的值。 

p i         -> 打印变量i //print 显示变量或表达式的值 

GDB print命令打印字符串全部内容

set print element 0

step 执行下一个源程序行,必要时进入下一个函数 

finish     -> 退出函数

breakpoint 在程序中设置一个断点 
b n        -> 打断点,在n行//break NUM 在指定的行上设置断点。 

为已存在断点添加命中条件  
使用 condition  N condition.  N是一个 breakpoint number.

(gdb) help condition 
Specify breakpoint number N to break only if COND is true. Usage is `condition N COND', where N is an integer and COND is an expression to be evaluated whenever breakpoint N is reached. 
(gdb) condition 1 i == 4


b func   -> 打断点,在函数func处
当你的多个文件中可能含有相同的函数名时必须给出文件名。
break FILENAME:FUNCTION
在文件名为FILENAME的FUNCTION函数上设置断点

break FILENAME:LINENUM   在文件名为FILENAME的原文件的第LINENUM行设置断点

条件断点: break line-or-function if expr
例:
(gdb) break 46 if testsize==100
(gdb) b 函数名称 if a==5//整数类型
(gdb) b 函数名称 if 0==strcmp(a,"abcdefg") //字符串类型比较 

break +OFFSET
break -OFFSET
当前程序运行到的前几行或后几行设置断点

break
当break命令不包含任何参数时,break命令在当前执行到的程序运行栈中的
下一条指令上设置一个断点
。除了栈底以外,这个命令使程序在一旦从当前
函数返回时停止。
相似的命令是finish,但finish并不设置断点。这一点在
循环语句中很有用。gdb在恢复执行时,至少执行一条指令。

ignore BNUM COUNT
设置第BNUM号断点的被忽略的次数为'COUNT',即断点BNUM再执行到第COUNT+1
次时程序停止

tbreak ARGS 或者简写为 tb
设置断点为只有效一次。ARGS的使用同break中的参量的使用

break *ADDRESS
在地址ADDRESS上设置断点,这个命令允许你在没有调试信息的程序中设置断点

hbreak ARGS
设置一个由硬件支持的断点。这个命令的主要目的是用于对EPROM/ROM程序的调试
因为这条命令可以在不改变代码的情况下设置断点。这可以同SPARCLite DSU一起
使用。当程序访问某些变量和代码时,DSU将设置“陷井”。注意:你只能一次使用
一个断点,在新设置断点时,先删除原断点

thbreak ARGS'
设置只有一次作用的硬件支持断点

rbreak REGEX
在所有满足表达式REGEX的函数上设置断点。这个命令在所有相匹配的函数上设置无
条件断点,当这个命令完成时显示所有被设置的断点信息。这个命令设置的断点和
break命令设置的没有什么不同。当调试C++程序时这个命令在重载函数上设置断点时
非常有用。

非常感谢GDB常用命令集锦_Phoenix_FuliMa-CSDN博客的分享,太棒了!!

watch 在程序中设置一个监测点(即数据断点) //GDB将把表达式加入到程序中并监
视程序的运行,当表达式的值被改变时GDB就使程序停止。 for、 while

Watchpoint 15 deleted because the program has left the block in

rwatch EXPR'
设置一个观察点,当EXPR被程序读时,程序被暂停。在多线程的程序中,观察点的作用很有限,GDB只能观察在一个线程中的表达式的值,如果你确信表达式只被当前线程所存取,那么使用观察点才有效。GDB不能注意一个非当前线程对表达式值的改变。

awatch EXPR'  //access watch
设置一个观察点,当EXPR被读出然后被写入时程序被暂停。

maint info breakpoints
显示所有的断点,无论是你设置的还是gdb自动设置的。
断点的含义:
breakpoint:断点,普通断点
watchpoint:普通观察点
longjmp:内部断点,用于处理'longjmp'调用
longjmp resume:内部断点,设置在'longjmp'调用的目标上
until:'until'命令所使用的内部断点
finish:finish'命令所使用的内部断点

clear 删除设置在特定源文件、特定行上的断点。

只有clear则是删除当前行断点,如果有的话。

其用法为clear FILENAME:NUM 

*删除所有断点: 
(gdb) delete 

delete 删除指定索引的断点   delete 0

info break显示 #0 #1 #2

list 显示源代码段。

list 列出相应于正在执行的程序的原文件内容

next 在不单步执行进入其他函数的情况下,向前执行一行源代码。

n           -> 执行下一行,单挑执行 //  

*执行N次下一步: 
(gdb) next N 

*执行上次执行的命令: 
(gdb) [Enter] 
这里,直接输入回车就会执行上次的命令了。  

 backtrace 显示程序中的当前位置和表示如何到达当前位置的栈跟踪(同义词:where) 

bt          -> 查看函数堆栈   //bt 显示所有的调用栈帧。该命令可用来显示函数的调用顺序。 

up 上移栈帧,使另一函数成为当前函数 

down 下移栈帧,使得另一个函数成为当前函数 

continue 继续执行正在调试的程序。

该命令用在程序由于处理信号、刚刚挂载进程 或断点而 导致停止运行时。

run 执行该程序 

r            -> 运行程序 //

quit 退出gdb 

q            -> 结束调试 //

常用命令(From:http://my.donews.com/tangfl/2006/10/23/gdb-debug-example/) 
 

 
  display EXPR 每次程序停止后显示表达式的值。表达式由程序定义的变量组成。 
  file FILE 装载指定的可执行文件进行调试。 
  help NAME 显示指定命令的帮助信息。 
  kill 终止正被调试的程序。 //kill 异常终止在gdb 控制下运行的程序 
  make 在不退出 gdb 的情况下运行 make 工具。 
cd 改变当前工作目录 
commands 命中断点时,列出将要执行的命令 
display 程序停止时显示变量和表达时 
frame 选择下一条continue命令的帧 
jump 在源程序中的另一点开始运行 
pwd 显示当前工作目录 
pype 显示一个数据结构(如一个结构或C++类)的内容 
reverse-search 在源文件中反向搜索正规表达式 
search 在源文件中搜索正规表达式 
set variable 给变量赋值 
signal 将一个信号发送到正在运行的进程 
undisplay display命令的反命令,不要显示表达式 
until 结束当前循环 
whatis 显示变量或函数类型

x /nxb    -> 以单字节(b)为单位,以十六进制形式显示(x),打印n(n)个字节。

*跳转执行程序到第5行: 
(gdb) jump 5 
这里,可以简写为"j 5"需要注意的是,跳转到第5行执行完毕之后,如果后面没有断点则继续执行,而并不是停在那里了。 
另外,跳转不会改变当前的堆栈内容,所以跳到别的函数中就会有奇怪的现象,因此最好跳转在一个函数内部进行,跳转的参数也可以是程序代码行的地址,函数名等等类似list。 

*强制返回当前函数: 
(gdb) return 
这样,将会忽略当前函数还没有执行完毕的语句,强制返回。return后面可以接一个表达式,表达式的返回值就是函数的返回值。 

*强制调用函数: 
(gdb) call <expr> 
这里,<expr>可以是一个函数,这样就会返回函数的返回值,如果函数的返回类型是void那么就不会打印函数的返回值,但是实践发现,函数运行过程中的打印语句还是没有被打印出来。 


*查看当前调试程序的语言环境: 
(gdb) show language 
这里,如果gdb不能识别你所调试的程序,那么默认是c语言。 

*查看当前函数的程序语言: 
(gdb) info frame 

*显示当前的调试源文件: 
(gdb) info source 
这样会显示当前所在的源代码文件信息,例如文件名称,程序语言等。 

*手动设置当前的程序语言为c++: 
(gdb) set language c++ 
这里,如果gdb没有检测出你的程序语言,你可以这样设置。 

*查看可以设置的程序语言: 
(gdb) set language 
这里,使用没有参数的set language可以查看gdb中可以设置的程序语言。 

*终止一个正在调试的程序: 
(gdb) kill 
这里,输入kill就会终止正在调试的程序了。 

*用16进制显示(var)值: 
(gdb) print /x var 
这里可以知道,print可以指定显示的格式,这里用'/x'表示16进制的格式。 
可以支持的变量显示格式有: 
x  按十六进制格式显示变量。 
d  按十进制格式显示变量。 
u  按十六进制格式显示无符号整型。 
o  按八进制格式显示变量。 
t  按二进制格式显示变量。 
a  按十六进制格式显示变量。 
c  按字符格式显示变量。 
f  按浮点数格式显示变量。 


*如果a是一个数组,10个元素,如果要显示则: 
(gdb) print *a@10 
这样,会显示10个元素,无论a是double或者是int的都会正确地显示10个元素。 


*修改运行时候的变量值: 
(gdb) print x=4 
这里,x=4是C/C++的语法,意为把变量x值改为4,如果你当前调试的语言是Pascal,那么你可以使用Pascal的语法:x:=4。 

*显示一个变量var的类型: 
(gdb) whatis var 

*以更详细的方式显示变量var的类型: 
(gdb) ptype var 
这里,会打印出var的结构定义。 


**没有实践过的 
*print显示存储块,如显示h后面的10个整数: 
print h@10 

https://www.cnblogs.com/zhoug2020/p/7283169.html

3.cont N
第N次经过该断点时才停止程序运行

4.enable 断点编号
恢复暂时失活的断点,要恢复多个编号的断点,可用空格将编号分开

5.disable 断点编号
使断点失效,但是断点还在
 

附加到进程调试:

gdb ../bin64/h5svr -p pid 别忘记c继续程序哦

gdb启动程序并带参数

gdb ../bin64/h5svr

gdb)  set args [-start mainsvr ] -f xxx.xml -c

gdb) run

$ gdb --args ../bin.x64/h5svr -start mainsvr -f xxx.xml -c

(gdb) run -start mainsvr -f xxx.xml -c

保存
(gdb) save breakpoint xxxx.bp
恢复
(gdb) source xxxx.bp(实际上就是gdb脚本)

http://sourceware.org/gdb/current/onlinedocs/refcard.pdf.gz
http://sourceware.org/gdb/documentation/

-g编译的程序去掉编译的调试信息,可以用strip a.exe

print /x /d /u /o /t(二进制) /f  /c(字符形式)

ptype 打印变量类型

  whatis 变量或表达式 ------- 显示变量或表达式的数据类型

(gdb) whatis buf
type = char [3]
(gdb) ptype buf
type = char [3]

修改变量的值  p data = 100

p data  打印显示100

   set variable 变量=值 ------ 给变量赋值

(gdb) set buf[0]='a'
(gdb) p buf
$1 = "a\345\377"
(gdb) p buf[1]='b'
$2 = 98 'b'
(gdb) p buf
$3 = "ab\377"
(gdb) 

打印全局变量  p 'xxx.cpp'::st_um

打印内存块内容,如果只用print *pData则只能打印一个pData类型的内存块,如果是char*则是一个字符,如果是char*[10] 类型则是10个字符。下面假设其是char* pData

要打印一段内容需要使用 print *pData@length  eg: p *pData@20

(加餐,gdb默认最多打印200字符,要打印超过200个字符需要先 设置  set print elements 0,然后再调用 p *pData@210 打印内存块中的210个字符)——置为0表示没有限制

examine命令(简写是x)来查看内存地址中的值。x命令的语法如下所示:

    x/<n/f/u> <addr>

  n、f、u是可选的参数。

  n是一个正整数,表示需要显示的内存单元的个数,也就是说从当前地址向后显示几个内存单元的内容,一个内存单元的大小由后面的u定义

  f 表示显示的格式,参见下面。如果地址所指的是字符串,那么格式可以是s,如果是指令地址,那么格式可以是i。

  u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4个bytes。u参数可以用下面的字符来代替,b表示单字节,h表示双字节,w表示四字 节,g表示八字节。当我们指定了字节长度后,GDB会从指内存定的内存地址开始,读写指定字节,并把其当作一个值取出来。

  <addr>表示一个内存地址。

  注意:严格区分n和u的关系,n表示单元个数,u表示每个单元的大小。

  n/f/u三个参数可以一起使用。例如:x/10tb buf

  命令:x/3uh 0x54320 表示,从内存地址0x54320读取内容,h表示以双字节为一个单位,3表示输出三个单位,u表示按无符号十进制显示。

监视点变量或监测变量设置 watch data

rwatch data (data值被读取则中止)和 awatch =(watch + rwatch)读写则中止

删除变量检测

(gdb) info watch
Num     Type           Disp Enb Address            What
2       hw watchpoint  keep y                      buf
        breakpoint already hit 2 times
(gdb) delete 2
(gdb) info watch

No watchpoints.

watch变量的使能和不能设置

(gdb) watch buf
Hardware watchpoint 3: buf
(gdb) info watch
Num     Type           Disp Enb Address            What
3       hw watchpoint  keep y                      buf
(gdb) disable 3
(gdb) info watch
Num     Type           Disp Enb Address            What
3       hw watchpoint  keep n                      buf
(gdb) enable 3
(gdb) i watch
Num     Type           Disp Enb Address            What
3       hw watchpoint  keep y                      buf
(gdb) 

enable once 3使能一次,触发后disable

enable delete 3 使能,触发后删除

观察点设置,观察变量 display data

watch和display设置监測点的差别:
   watch监測仅仅有当监測的变量值发生变化时才显示变量,并且旧值和新值都会显示。
   display监測每一次执行命令都会显示变量的值,仅仅会显示变量的最新值。

查看和删除display

(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
1:   y  buf
(gdb) undisplay 1

不能和使能display

(gdb) display buf
2: buf = 0x7fffffffe4e0
(gdb) info display
Auto-display expressions now in effect:
Num Enb Expression
2:   y  buf
(gdb) disable display 2
(gdb) info display

Auto-display expressions now in effect:
Num Enb Expression
2:   n  buf
(gdb) enable display 2
(gdb) info display

Auto-display expressions now in effect:
Num Enb Expression
2:   y  buf

设置条件断点  break filenum if condi==2

忽略断点n次 ignore

info break

$1xxxx

$2 xxx

ignore 2 10  //忽略断点命中10次

next  单步执行程序,遇到函数调用不会进入

step  单步执行程序,遇到函数调用会进入

next cnt 一次执行多步

step cnt 一次执行多步,会进入函数

nexti  // nexti/stepi --------------- 单步运行一条机器指令

(gdb) ni
0x00000000004005c9      11         printf("44\n");
(gdb) n
44
12         print();

stepi  指令形式执行

(gdb) si
0x00000000004005a6      4          printf("xxxx");
(gdb) 
0x00000000004005ab      4          printf("xxxx");
(gdb) 
0x0000000000400470 in printf@plt ()

until ====循环体最后一句时,执行完循环后在循环外停止

until line  ====停止在某行

jump location  可以修改代码执行逻辑,执行原本不可能执行到的代码,

(gdb) jump print()
Line 4 is not in `main()'.  Jump anyway? (y or n) y
Continuing at 0x4005f1.

Breakpoint 1, print () at main.cpp:4
4          printf("xxxx");

(gdb) jump 4
Line 4 is not in `main()'.  Jump anyway? (y or n) y
Continuing at 0x4005f1.

Breakpoint 1, print () at main.cpp:4
4          printf("xxxx");

finish 立即执行完函数后返回

return直接返回,不会执行下面的代码,可以指定函数返回值

disassemble

查看栈信息 bt (backtrace)

$1 ssss休息休息

$2  xxxx西溪湿地

切换栈编号  frame 2

$2  xxxx西溪湿地

===========gdbserver =============

server端启动
[root@VM-4-7-centos ~]# gdbserver 127.0.0.1:8818 a.out  
或gdbserver 127.0.0.1:8818 attach 28678

Process a.out created; pid = 28678
Listening on port 8818
Remote debugging from host 127.0.0.1
print %
Detaching from process 28678
 

客户端启动
[root@VM-4-7-centos ~]# gdb 

(gdb) target remote 127.0.0.1:8818
Remote debugging using 127.0.0.1:8818
warning: Could not load vsyscall page because no executable was specified
0x00007ffff7ddc140 in ?? ()
(gdb) l
No symbol table is loaded.  Use the "file" command.
(gdb) file a.out
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from /root/a.out...done.
(gdb) l
1       #include <stdio.h>
2
3       int main(){
4          int a = 100;  
5        printf("print %%\n");
6          return 0;
7       }
(gdb) b 5
Breakpoint 1 at 0x40056c: file m.cpp, line 5. 
(gdb) c
Continuing.
Breakpoint 1, main () at m.cpp:5
5        printf("print %%\n");
(gdb) n
6          return 0;
(gdb) detach
Detaching from program: /root/a.out, process 28678
Ending remote debugging.
[Inferior 1 (process 28678) detached]
(gdb) quit

============================================

4、gdb选项(gdb中好多命令都有自己的简写字母):
   不输入直接回车 ------------ 反复运行上一条命令
   q(quit) ------------------- 退出gdb
   file filename ------------- 打开文件filename
   l(list) ------------------- 显示10行代码。若再次执行则显示接下来10行代码
   list 5,10 ---------------- 显示第5到10行的代码
   list test.c:5,10 -------- 显示源文件test.c中第5到10行的代码
   list get_sum -------------- 显示get_sum函数周围的代码
   list test.c:get_sum ------- 显示源文件test.c中get_sum函数周围的代码
   shell XXX ----------------- 执行shell命令XXX
   search/forward str -------- 从当前行向前查找第一个匹配的字符串str
   reverse-search str -------- 从当前行向后查找第一个匹配的字符串str
   r(run) -------------------- 执行程序
   help XXX ------------------ 查看命令XXX的用法
   help all ------------------ 查看全部命令的用法
   whatis 变量或表达式 ------- 显示变量或表达式的数据类型
   set variable 变量=值 ------ 给变量赋值
   kill ---------------------- 结束当前程序的调试
   continue ------------------ 让程序继续执行,直到下一个断点或者执行完为止
   n(next) ------------------- 继续运行下一条语句,遇到函数把函数当作一条语句来运行
   step ---------------------- 继续运行下一条代码,遇到函数会跟踪进入函数
   nexti/stepi --------------- 单步运行一条机器指令
   watch 变量名 -------------- 设置变量监測点
   bt(backtrace) ------------- 显示程序当前执行位置和对当前位置的栈跟踪
   display 变量或表达式 ------ 加入观察点。以后每次执行命令都会显示相应变量或表达式的值
   undisplay num ------------- num为设置的display编号,能够用info display获取。不能用变量名

5、设置断点:
   b(break) 行号 ----------------------- 在第n行设置断点
   break fun_name ---------------------- 为函数fun_name设置断点
   break 行号或函数名 if 条件 ---------- 程序在执行中。当条件满足时。在某行中断暂停执行
   watch 条件表达式 -------------------- 程序执行中,满足条件时暂停执行,不须要写行号
   info breakpoints -------------------- 查看当前全部的断点
   disable 断点编号 -------------------- 使断点n失效
   enable 断点编号 --------------------- 使断点n有效
   clear ------------------------------- 删除本行断点(假设存在的话)
   clear 行号 -------------------------- 删除此行断点
   clear 函数名 ------------------------ 删除该函数的断点
   delete 断点编号 --------------------- 删除指定编号的断点

6、print命令:
   print XXX ------------------------------- 打印输出XXX的值
   print 变量 = 值 ------------------------- 对变量赋值
   print 表达式@要打印值的个数n ------------ 打印以表达式值開始的n个数

7、watch和display设置监測点的差别:
   watch监測仅仅有当监測的变量值发生变化时才显示变量,并且旧值和新值都会显示。
   display监測每一次执行命令都会显示变量的值,仅仅会显示变量的最新值。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要对SLAM程序进行GDB调试,首先需要进入GDB调试环境。可以使用命令"gdb [程序名]"来进入GDB调试。例如,在ORB_SLAM3的ROS示例中,可以使用命令"gdb Stereo"进入GDB调试环境。 进入GDB调试后,可以使用一些常用的GDB命令进行调试。例如,可以使用"run"命令来运行程序,使用"break"命令设置断点,使用"step"命令逐行执行程序,使用"print"命令打印变量的值等等。这些命令可以帮助我们分析程序的执行过程和调试问题。 请注意,GDB是一个命令行模式的调试工具,因此需要熟悉一些基本的GDB命令才能进行有效的调试。在GDB调试过程中,可以通过加上"-q"参数来禁止输出一些不必要的信息,以便更清晰地查看调试信息。 总结一下,要对SLAM程序进行GDB调试,可以使用"gdb [程序名]"命令进入GDB调试环境,并使用一些常用的GDB命令进行调试,例如"run"、"break"、"step"、"print"等命令[2]。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [SLAM工具|GDB调试从入门到精通](https://blog.csdn.net/Yong_Qi2015/article/details/122463019)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [GDB调试 ORBSLAM3](https://blog.csdn.net/qq_41861406/article/details/125034738)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值