GDB
调试工具学习笔记
1.GDB
是什么东西?
GDB
是 GNU
开源组织发布的调试器,允许你查看另一个程序在运行过程中内部发生了什么,或者当另外一个程序崩溃了后,内部正在执行什么。
2.解决什么问题?
GDB
主要可以做四种事情来帮助你捕获 bugs
:
- (1) 启动程序,设置可影响程序行为的任意参数;
- (2) 让你的程序在指定条件下暂停;
- (3) 当程序停止时,检查发生了什么;
- (4) 改变程序中内容,这样你可以尝试纠正一个bug的影响并继续了解另一个;
3.快速上手使用
3.1 安装 GDB
工具
# 1.安装gdb工具
>> sudo apt-get install gdb
# 2.查看gdb版本
>> gdb --version
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.2) 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.
3.2 快速上手 GDB
- (1) 创建一个
main.cc
/*
* @Author: chenjingyu
* @Date: 2025-01-05 16:35:42
* @Contact: 2458006466@qq.com
* @Description: main
*/
#include <iostream>
#include <vector>
void Hello() {
std::cout << "Hello, World.\n";
}
int main(int argc, char *argv[]) {
std::vector<int> vec {1, 2, 3, 4, 5, 6};
for (auto v : vec) {
std::cout << v << "\n";
}
Hello();
return 0;
}
- (2) 编译程序:-g选项表示生成调试信息
>> g++ -g -o main main.cc
- (3)
gdb
调试:r表示运行程序,q表示退出调试
>> gdb ./main
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.2) 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:
--Type <RET> for more, q to quit, c to continue without paging--
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./main...
(gdb) r
Starting program: /home/mirror/workspace/test/main
1
2
3
4
5
6
[Inferior 1 (process 2583) exited normally]
(gdb) q
- (4) 打断点及单步运行:
break(b)
打断点(函数名或行号),list
查看源代码,info b
查看断点信息,next(n)
单步运行
(gdb)b main
Breakpoint 1 at 0x1289: file main.cc, line 10.
(gdb) list 1,20
1 /*
2 * @Author: chenjingyu
3 * @Date: 2025-01-05 16:35:42
4 * @Contact: 2458006466@qq.com
5 * @Description: main
6 */
7 #include <iostream>
8 #include <vector>
9
10 void Hello() {
11 std::cout << "Hello, World.\n";
--Type <RET> for more, q to quit, c to continue without paging--
12 }
13
14 int main(int argc, char *argv[]) {
15 std::vector<int> vec {1, 2, 3, 4, 5, 6};
16 for (auto v : vec) {
17 std::cout << v << "\n";
18 }
19 Hello();
20
(gdb) b 17
Breakpoint 2 at 0x137a: file main.cc, line 17.
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x00000000000012a7 in main(int, char**) at main.cc:14
2 breakpoint keep y 0x0000000000001398 in main(int, char**) at main.cc:17
(gdb) r
Starting program: /home/mirror/workspace/test/main
Breakpoint 1, main (argc=21845, argv=0x555555559151 <std::__ioinit>) at main.cc:14
14 int main(int argc, char *argv[]) {
(gdb) n
15 std::vector<int> vec {1, 2, 3, 4, 5, 6};
(gdb) n
16 for (auto v : vec) {
(gdb) n
Breakpoint 2, main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) n
1
16 for (auto v : vec) {
(gdb) q
A debugging session is active.
Inferior 1 [process 6728] will be killed.
Quit anyway? (y or n) y
3.3 更多 GDB
命令及小技巧
- (1)
print
、util
和step
:print(p)
打印变量内容,util(u)
程序运行至第n
行,step(s)
进入函数内部
>> gdb ./main
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.2) 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:
--Type <RET> for more, q to quit, c to continue without paging--
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./main...
(gdb) b main
Breakpoint 1 at 0x12a7: file main.cc, line 14.
(gdb) list 1,20
1 /*
2 * @Author: chenjingyu
3 * @Date: 2025-01-05 16:35:42
4 * @Contact: 2458006466@qq.com
5 * @Description: main
6 */
7 #include <iostream>
8 #include <vector>
9
10 void Hello() {
11 std::cout << "Hello, World.\n";
--Type <RET> for more, q to quit, c to continue without paging--
12 }
13
14 int main(int argc, char *argv[]) {
15 std::vector<int> vec {1, 2, 3, 4, 5, 6};
16 for (auto v : vec) {
17 std::cout << v << "\n";
18 }
19 Hello();
20
(gdb) r
Starting program: /home/mirror/workspace/test/main
Breakpoint 1, main (argc=21845, argv=0x555555559151 <std::__ioinit>) at main.cc:14
14 int main(int argc, char *argv[]) {
(gdb) u 19
1
2
3
4
5
6
main (argc=1, argv=0x7fffffffd258) at main.cc:19
19 Hello();
(gdb) s
Hello () at main.cc:10
10 void Hello() {
(gdb) n
11 std::cout << "Hello, World.\n";
(gdb) n
Hello, World.
12 }
(gdb) n
main (argc=1, argv=0x7fffffffd258) at main.cc:21
21 return 0;
(gdb) n
15 std::vector<int> vec {1, 2, 3, 4, 5, 6};
(gdb) n
22 }
(gdb) n
__libc_start_main (main=0x5555555552a7 <main(int, char**)>, argc=1, argv=0x7fffffffd258,
init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffd248)
at ../csu/libc-start.c:342
342 ../csu/libc-start.c: No such file or directory.
(gdb) q
A debugging session is active.
Inferior 1 [process 10642] will be killed.
Quit anyway? (y or n) y
- (2)
shell
终端命令调用及日志功能:(a)shell
调用终端的命令,如,shell ls
调用shell
的ls
命令;(b) 日志功能:set logging on
,gdb
会开始记录你当前操作及打印结果,并输出到gdb.txt
文件中。
gdb ./main
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.2) 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:
--Type <RET> for more, q to quit, c to continue without paging--
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./main...
(gdb) shell ls
main main.cc
(gdb) shell cat main.cc
/*
* @Author: chenjingyu
* @Date: 2025-01-05 16:35:42
* @Contact: 2458006466@qq.com
* @Description: main
*/
#include <iostream>
#include <vector>
void Hello() {
std::cout << "Hello, World.\n";
}
int main(int argc, char *argv[]) {
std::vector<int> vec {1, 2, 3, 4, 5, 6};
for (auto v : vec) {
std::cout << v << "\n";
}
Hello();
return 0;
}
(gdb) set logging on
Copying output to gdb.txt.
Copying debug output to gdb.txt.
(gdb) b main
Breakpoint 1 at 0x12a7: file main.cc, line 14.
(gdb) list 1, 20
1 /*
2 * @Author: chenjingyu
3 * @Date: 2025-01-05 16:35:42
4 * @Contact: 2458006466@qq.com
5 * @Description: main
6 */
7 #include <iostream>
8 #include <vector>
9
10 void Hello() {
11 std::cout << "Hello, World.\n";
--Type <RET> for more, q to quit, c to continue without paging--
12 }
13
14 int main(int argc, char *argv[]) {
15 std::vector<int> vec {1, 2, 3, 4, 5, 6};
16 for (auto v : vec) {
17 std::cout << v << "\n";
18 }
19 Hello();
20
(gdb) b 17
Breakpoint 2 at 0x1398: file main.cc, line 17.
(gdb) r
Starting program: /home/mirror/workspace/test/main
Breakpoint 1, main (argc=21845, argv=0x555555559151 <std::__ioinit>) at main.cc:14
14 int main(int argc, char *argv[]) {
(gdb) n
15 std::vector<int> vec {1, 2, 3, 4, 5, 6};
(gdb) n
16 for (auto v : vec) {
(gdb) n
Breakpoint 2, main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) n
1
16 for (auto v : vec) {
(gdb) n
Breakpoint 2, main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) n
2
16 for (auto v : vec) {
(gdb) n
Breakpoint 2, main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) n
3
16 for (auto v : vec) {
(gdb) n
Breakpoint 2, main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) n
4
16 for (auto v : vec) {
(gdb) n
Breakpoint 2, main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) n
5
16 for (auto v : vec) {
(gdb) n
Breakpoint 2, main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) n
6
16 for (auto v : vec) {
(gdb) n
19 Hello();
(gdb) n
Hello, World.
21 return 0;
(gdb) n
15 std::vector<int> vec {1, 2, 3, 4, 5, 6};
(gdb) n
22 }
(gdb) n
__libc_start_main (main=0x5555555552a7 <main(int, char**)>, argc=1, argv=0x7fffffffd258, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
stack_end=0x7fffffffd248) at ../csu/libc-start.c:342
342 ../csu/libc-start.c: No such file or directory.
(gdb) q
A debugging session is active.
Inferior 1 [process 13442] will be killed.
Quit anyway? (y or n) y
(3) 观察点 watch point
:使用 watch
命令添加观察点,来查看变量是否发生变化及对于程序影响:
>> gdb ./main
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.2) 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:
--Type <RET> for more, q to quit, c to continue without paging--
<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 ./main...
(gdb) list 1,20
1 /*
2 * @Author: chenjingyu
3 * @Date: 2025-01-05 16:35:42
4 * @Contact: 2458006466@qq.com
5 * @Description: main
6 */
7 #include <iostream>
8 #include <vector>
9
10 void Hello() {
11 std::cout << "Hello, World.\n";
--Type <RET> for more, q to quit, c to continue without paging--
12 }
13
14 int main(int argc, char *argv[]) {
15 std::vector<int> vec {1, 2, 3, 4, 5, 6};
16 for (auto v : vec) {
17 std::cout << v << "\n";
18 }
19 Hello();
20
(gdb) b 16
Breakpoint 1 at 0x1348: file main.cc, line 16.
(gdb) r
Starting program: /home/mirror/workspace/test/main
Breakpoint 1, main (argc=1, argv=0x7fffffffd258) at main.cc:16
16 for (auto v : vec) {
(gdb) p &v
$1 = (int *) 0x7fffffffd0e4
(gdb) watch *0x7fffffffd0e4
Hardware watchpoint 2: *0x7fffffffd0e4
(gdb) info watchpoint
Num Type Disp Enb Address What
2 hw watchpoint keep y *0x7fffffffd0e4
(gdb) n
Hardware watchpoint 2: *0x7fffffffd0e4
Old value = 32767
New value = 1
main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) n
1
16 for (auto v : vec) {
(gdb) n
Hardware watchpoint 2: *0x7fffffffd0e4
Old value = 1
New value = 2
main (argc=1, argv=0x7fffffffd258) at main.cc:17
17 std::cout << v << "\n";
(gdb) q
A debugging session is active.
Inferior 1 [process 15239] will be killed.
Quit anyway? (y or n) y
4.调试 core
文件
(1) 编写测试代码:
/*
* @Author: chenjingyu
* @Date: 2025-01-05 16:35:42
* @Contact: 2458006466@qq.com
* @Description: main
*/
#include <iostream>
int main(int argc, char *argv[]) {
int *a = nullptr;
// 段错误
*a = 10;
std::cout << *a << std::endl;
return 0;
}
(2) 编译运行:
>> g++ -g -o main main.cc
>> ./main
[1] 17421 segmentation fault (core dumped) ./main
这里不会生成core文件,若想生成core文件,需要对主机开启限制:
# 1.查看限制
>> ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) 0
-m: resident set size (kbytes) unlimited
-u: processes 31757
-n: file descriptors 1024
-l: locked-in-memory size (kbytes) 65536
-v: address space (kbytes) unlimited
-x: file locks unlimited
-i: pending signals 31757
-q: bytes in POSIX msg queues 819200
-e: max nice 0
-r: max rt priority 0
-N 15: unlimited
# 2.开启core文件限制
>> ulimit -c unlimited
>> ulimit -a
-t: cpu time (seconds) unlimited
-f: file size (blocks) unlimited
-d: data seg size (kbytes) unlimited
-s: stack size (kbytes) 8192
-c: core file size (blocks) unlimited
-m: resident set size (kbytes) unlimited
-u: processes 31757
-n: file descriptors 1024
-l: locked-in-memory size (kbytes) 65536
-v: address space (kbytes) unlimited
-x: file locks unlimited
-i: pending signals 31757
-q: bytes in POSIX msg queues 819200
-e: max nice 0
-r: max rt priority 0
-N 15: unlimited
# 3.kernel开启core_pattern
>> sudo vim /etc/sysctl.conf
kernel.core_pattern = ./core.%t
>> sudo sysctl -p /etc/sysctl.conf
vm.overcommit_memory = 1
kernel.core_pattern = ./core.%t
# 4.运行程序,就可以生成core文件
>> ./main
[1] 20608 segmentation fault (core dumped) ./main
>> ls
core.1736071149 main main.cc
- (3) 调试core文件:可以看到错误在第10行
>> gdb ./main core.1736071149
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.2) 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 ./main...
[New LWP 21783]
Core was generated by `./main'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x000055c80f5671c8 in main (argc=1, argv=0x7ffeeab671f8)
at main.cc:10
10 *a = 10;
(gdb) q
5.调试正在运行程序
- (1) 编写测试代码
/*
* @Author: chenjingyu
* @Date: 2025-01-05 16:35:42
* @Contact: 2458006466@qq.com
* @Description: main
*/
void test() {
}
void test1() {
int i = 0;
i++;
}
int main(int argc, char *argv[]) {
for (;;) {
test();
test1();
}
return 0;
}
- (2) 编译运行及调试
# 1.编译
>> g++ -o main main.cc
# 2.后台运行
>> ./main &
[1] 23320
# 3.手动获取进程号
>> ps -ef | grep main
mirror 975 971 0 16:35 pts/2 00:00:08 /home/mirror/.vscode-server/bin/fabdb6a30b49f79a7aba0f2ad9df9b399473380f/node /home/mirror/.vscode-server/bin/fabdb6a30b49f79a7aba0f2ad9df9b399473380f/out/server-main.js --host=127.0.0.1 --port=0 --connection-token=1530006837-1003603819-2446901564-2060308145 --use-host-proxy --without-browser-env-var --disable-websocket-compression --accept-server-license-terms --telemetry-level=all
mirror 23320 16912 46 18:05 pts/0 00:00:56 ./main
mirror 23744 23700 0 18:07 pts/5 00:00:00 grep --color=auto --exclude-dir=.bzr --exclude-dir=CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn --exclude-dir=.idea --exclude-dir=.tox --exclude-dir=.venv --exclude-dir=venv main
# 4.调试,-p指定进程号
>> gdb -p 23320
GNU gdb (Ubuntu 9.2-0ubuntu1~20.04.2) 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".
Attaching to process 23320
Reading symbols from /home/mirror/workspace/test/main...
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...
Reading symbols from /usr/lib/debug/.build-id/07/02430aef5fa3dda43986563e9ffcc47efbd75e.debug...
Reading symbols from /lib64/ld-linux-x86-64.so.2...
Reading symbols from /usr/lib/debug/.build-id/db/0420f708b806cf03260aadb916c330049580b7.debug...
test () at main.cc:8
8 void test() {
(gdb) n
10 }
(gdb) n
main (argc=1, argv=0x7fff63bb17f8) at main.cc:20
20 test1();
(gdb) s
test1 () at main.cc:12
12 void test1() {
(gdb) n
13 int i = 0;
(gdb) n
14 i++;
(gdb) p i
$1 = 0
(gdb) n
15 }
(gdb) p i
$2 = 1
(gdb) n
main (argc=1, argv=0x7fff63bb17f8) at main.cc:19
19 test();
(gdb) n
20 test1();
(gdb) n
19 test();
(gdb) n
20 test1();
(gdb) n
19 test();
(gdb) q
A debugging session is active.
Inferior 1 [process 23320] will be detached.
Quit anyway? (y or n) y
Detaching from program: /home/mirror/workspace/test/main, process 23320
[Inferior 1 (process 23320) detached]
参考资料
- [1]
GDB
官方文档 - [2] wsl ubuntu20.04设置core文件生成路径
- [3] 一小时入门GDB