GDB调试工具学习笔记

MirrorYuChen
MirrorYuChen
发布于 2025-01-05 / 61 阅读
0
0

GDB调试工具学习笔记

GDB调试工具学习笔记

1.GDB是什么东西?

​ GDBGNU开源组织发布的调试器,允许你查看另一个程序在运行过程中内部发生了什么,或者当另外一个程序崩溃了后,内部正在执行什么。

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) printutilstepprint(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调用 shellls命令;(b) 日志功能:set logging ongdb会开始记录你当前操作及打印结果,并输出到 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]

参考资料


评论