huhan@HuHan ~/cpp/coredump ls
test.cpp
huhan@HuHan ~/cpp/coredump
huhan@HuHan ~/cpp/coredump g++ -o test test.cpp -g
huhan@HuHan ~/cpp/coredump ulimit
unlimited
huhan@HuHan ~/cpp/coredump ulimit- c unlimited
zsh: command not found: ulimit-
✘ huhan@HuHan ~/cpp/coredump ulimit -c unlimied
ulimit: invalid number: unlimied
✘ huhan@HuHan ~/cpp/coredump ulimit -c unlimited
huhan@HuHan ~/cpp/coredump
huhan@HuHan ~/cpp/coredump g++ -o test test.cpp -g
huhan@HuHan ~/cpp/coredump ulimit -c unlimited
huhan@HuHan ~/cpp/coredump lstest test.cpp
huhan@HuHan ~/cpp/coredump ./test
10[1]290 segmentation fault (core dumped) ./test
✘ huhan@HuHan ~/cpp/coredump gdb test core
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 test...
[New LWP 290]
Core was generated by `./test'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00005586369c71f9 in func (p=0x0) at test.cpp:6
6 int y = *p;
(gdb) where
#0 0x00005586369c71f9 in func (p=0x0) at test.cpp:6
#1 0x00005586369c7296 in main () at test.cpp:19
(gdb) l
1 #include <iostream>
2 using namespace std;
3
4 int func(int *p)
5 {
6 int y = *p;
7 return y;
8 }
9
10 int add(int const& a, int const& b)
(gdb) l
11 {
12 return a + b;
13 }
14
15 int main()
16 {
17 cout<< add(4, 6) <<endl;
18 int *p = NULL;
19 return func(p);
20 }
(gdb) b 5
Breakpoint 1 at 0x5586369c71e9: file test.cpp, line 5.
(gdb) b 13
Breakpoint 2 at 0x5586369c7221: file test.cpp, line 13.
(gdb) b 17
Breakpoint 3 at 0x5586369c723e: file test.cpp, line 17.
(gdb) b main
Breakpoint 4 at 0x5586369c7223: file test.cpp, line 16.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00005586369c71e9 in func(int*) at test.cpp:5
2 breakpoint keep y 0x00005586369c7221 in add(int const&, int const&) at test.cpp:13
3 breakpoint keep y 0x00005586369c723e in main() at test.cpp:17
4 breakpoint keep y 0x00005586369c7223 in main() at test.cpp:16
(gdb) r
Starting program: /home/huhan/cpp/coredump/test
Breakpoint 4, main () at test.cpp:16
16 {
(gdb) s
Breakpoint 3, main () at test.cpp:17
17 cout<< add(4, 6) <<endl;
(gdb) s
add (a=@0x55555555537d: 29590344, b=<error reading variable>) at test.cpp:11
11 {
(gdb) s
12 return a + b;
(gdb) p a
$1 = (const int &) @0x7fffffffdae8: 4
(gdb) n
Breakpoint 2, add (a=@0x7fffffffdae8: 4, b=@0x7fffffffdaec: 6) at test.cpp:13
13 }
(gdb) n
10
main () at test.cpp:18
18 int *p = NULL;
(gdb) n
19 return func(p);
(gdb) disassemble
Dump of assembler code for function main():
0x0000555555555223 <+0>: endbr64
0x0000555555555227 <+4>: push %rbp
0x0000555555555228 <+5>: mov %rsp,%rbp
0x000055555555522b <+8>: sub $0x20,%rsp
0x000055555555522f <+12>: mov %fs:0x28,%rax
0x0000555555555238 <+21>: mov %rax,-0x8(%rbp)
0x000055555555523c <+25>: xor %eax,%eax
0x000055555555523e <+27>: movl $0x6,-0x14(%rbp)
0x0000555555555245 <+34>: movl $0x4,-0x18(%rbp)
0x000055555555524c <+41>: lea -0x14(%rbp),%rdx
0x0000555555555250 <+45>: lea -0x18(%rbp),%rax
0x0000555555555254 <+49>: mov %rdx,%rsi
0x0000555555555257 <+52>: mov %rax,%rdi
0x000055555555525a <+55>: callq 0x555555555203 <add(int const&, int const&)>
0x000055555555525f <+60>: mov %eax,%esi
0x0000555555555261 <+62>: lea 0x2dd8(%rip),%rdi # 0x555555558040 <_ZSt4cout@@GLIBCXX_3.4>
0x0000555555555268 <+69>: callq 0x5555555550e0 <_ZNSolsEi@plt>
0x000055555555526d <+74>: mov %rax,%rdx
0x0000555555555270 <+77>: mov 0x2d59(%rip),%rax # 0x555555557fd0
0x0000555555555277 <+84>: mov %rax,%rsi
0x000055555555527a <+87>: mov %rdx,%rdi
0x000055555555527d <+90>: callq 0x5555555550b0 <_ZNSolsEPFRSoS_E@plt>
0x0000555555555282 <+95>: movq $0x0,-0x10(%rbp)
=> 0x000055555555528a <+103>: mov -0x10(%rbp),%rax
0x000055555555528e <+107>: mov %rax,%rdi
0x0000555555555291 <+110>: callq 0x5555555551e9 <func(int*)>
0x0000555555555296 <+115>: nop
0x0000555555555297 <+116>: mov -0x8(%rbp),%rcx
0x000055555555529b <+120>: xor %fs:0x28,%rcx
0x00005555555552a4 <+129>: je 0x5555555552b9 <main()+150>
0x00005555555552a6 <+131>: jmp 0x5555555552b4 <main()+145>
0x00005555555552a8 <+133>: endbr64
0x00005555555552ac <+137>: mov %rax,%rdi
0x00005555555552af <+140>: callq 0x5555555550f0 <_Unwind_Resume@plt>
0x00005555555552b4 <+145>: callq 0x5555555550c0 <__stack_chk_fail@plt>
0x00005555555552b9 <+150>: leaveq
0x00005555555552ba <+151>: retq
End of assembler dump.
(gdb) s
Breakpoint 1, func (p=0x555555555330 <__libc_csu_init>) at test.cpp:5
5 {
(gdb) s
6 int y = *p;
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00005555555551f9 in func (p=0x0) at test.cpp:6
6 int y = *p;
(gdb) q
A debugging session is active.
Inferior 1 [process 299] will be killed.
Quit anyway? (y or n) n
Not confirmed.
(gdb) info frame
Stack level 0, frame at 0x7fffffffdae0:
rip = 0x5555555551f9 in func (test.cpp:6); saved rip = 0x555555555296
called by frame at 0x7fffffffdb10
source language c++.
Arglist at 0x7fffffffdac8, args: p=0x0
Locals at 0x7fffffffdac8, Previous frame's sp is 0x7fffffffdae0
Saved registers:
rbp at 0x7fffffffdad0, rip at 0x7fffffffdad8
(gdb) n
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) q
huhan@HuHan ~/cpp/coredump
run # 运行程序
run {args} # 以某参数运行程序
run < file # 以某文件为标准输入运行程序
run < <(cmd) # 以某命令的输出作为标准输入运行程序
run <<< $(cmd) # 以某命令的输出作为标准输入运行程序
set args {args} ... # 设置运行的参数
show args # 显示当前的运行参数
cont # 继续运行,可简写为 c
step # 单步进入,碰到函数会进去
step {count} # 单步多少次
next # 单步跳过,碰到函数不会进入
next {count} # 单步多少次
CTRL+C # 发送 SIGINT 信号,中止当前运行的程序
attach {process-id} # 链接上当前正在运行的进程,开始调试
detach # 断开进程链接
finish # 结束当前函数的运行
until # 持续执行直到代码行号大于当前行号(跳出循环)
until {line} # 持续执行直到执行到某行
kill # 杀死当前运行的函数
栈帧
bt # 打印 backtrace
frame # 显示当前运行的栈帧
up # 向上移动栈帧(向着 main 函数)
down # 向下移动栈帧(远离 main 函数)
info locals # 打印帧内的相关变量
info args # 打印函数的参数
代码浏览
list 101 # 显示第 101 行周围 10行代码
list 1,10 # 显示 1 到 10 行代码
list main # 显示函数周围代码
list basic.c:main # 显示另外一个源代码文件的函数周围代码
list - # 重复之前 10 行代码
list *0x22e4 # 显示特定地址的代码
cd dir # 切换当前目录
pwd # 显示当前目录
search {regexpr} # 向前进行正则搜索
reverse-search {regexp} # 向后进行正则搜索
dir {dirname} # 增加源代码搜索路径
dir # 复位源代码搜索路径(清空)
show directories # 显示源代码路径
浏览数据
print {expression} # 打印表达式,并且增加到打印历史
print /x {expression} # 十六进制输出,print 可以简写为 p
print array[i]@count # 打印数组范围
print $ # 打印之前的变量
print *$->next # 打印 list
print $1 # 输出打印历史里第一条
print ::gx # 将变量可视范围(scope)设置为全局
print 'basic.c'::gx # 打印某源代码里的全局变量,(gdb 4.6)
print /x &main # 打印函数地址
x *0x11223344 # 显示给定地址的内存数据
x /nfu {address} # 打印内存数据,n是多少个,f是格式,u是单位大小
x /10xb *0x11223344 # 按十六进制打印内存地址 0x11223344 处的十个字节
x/x &gx # 按十六进制打印变量 gx,x和斜杆后参数可以连写
x/4wx &main # 按十六进制打印位于 main 函数开头的四个 long
x/gf &gd1 # 打印 double 类型
help x # 查看关于 x 命令的帮助
info locals # 打印本地局部变量
info functions {regexp} # 打印函数名称
info variables {regexp} # 打印全局变量名称
ptype name # 查看类型定义,比如 ptype FILE,查看 FILE 结构体定义
whatis {expression} # 查看表达式的类型
set var = {expression} # 变量赋值
display {expression} # 在单步指令后查看某表达式的值
undisplay # 删除单步后对某些值的监控
info display # 显示监视的表达式
show values # 查看记录到打印历史中的变量的值 (gdb 4.0)
info history # 查看打印历史的帮助 (gdb 3.5)
info signals # 打印信号设置
handle {signo} {actions} # 设置信号的调试行为
handle INT print # 信号发生时打印信息
handle INT noprint # 信号发生时不打印信息
handle INT stop # 信号发生时中止被调试程序
handle INT nostop # 信号发生时不中止被调试程序
handle INT pass # 调试器接获信号,不让程序知道
handle INT nopass # 调试器不接获信号
signal signo # 继续并将信号转移给程序
signal 0 # 继续但不把信号给程序
线程调试
info threads # 查看当前线程和 id
thread {id} # 切换当前调试线程为指定 id 的线程
break {line} thread all # 所有线程在指定行号处设置断点
thread apply {id..} cmd # 指定多个线程共同执行 gdb 命令
thread apply all cmd # 所有线程共同执行 gdb 命令
set schedule-locking ? # 调试一个线程时,其他线程是否执行,off|on|step
set non-stop on/off # 调试一个线程时,其他线程是否运行
set pagination on/off # 调试一个线程时,分页是否停止
set target-async on/off # 同步或者异步调试,是否等待线程中止的信息
进程调试
info inferiors # 查看当前进程和 id
inferior {id} # 切换某个进程
kill inferior {id...} # 杀死某个进程
set detach-on-fork on/off # 设置当进程调用fork时gdb是否同时调试父子进程
set follow-fork-mode parent/child # 设置当进程调用fork时是否进入子进程
汇编调试
info registers # 打印普通寄存器
info all-registers # 打印所有寄存器
print/x $pc # 打印单个寄存器
stepi # 指令级别单步进入,可以简写为 si
nexti # 指令级别单步跳过,可以简写为 ni
display/i $pc # 监控寄存器(每条单步完以后会自动打印值)
x/x &gx # 十六进制打印变量
info line 22 # 打印行号为 22 的内存地址信息
info line *0x2c4e # 打印给定内存地址对应的源代码和行号信息
disassemble {addr} # 对地址进行反汇编,比如 disassemble 0x2c4e
历史信息
show commands # 显示历史命令 (gdb 4.0)
info editing # 显示历史命令 (gdb 3.5)
ESC-CTRL-J # 切换到 Vi 命令行编辑模式
set history expansion on # 允许类 c-shell 的历史
break class::member # 在类成员处设置断点
list class:member # 显示类成员代码
ptype class # 查看类包含的成员
print *this # 查看 this 指针