Linux编程系列——gdb

  • 添加调试信息(-g)
    g++ -std=c++11 -g
/* 一打印hello world 为例 */
#include <iostream>

using namespace std;

void test()
{
    
    
    cout << "hello world" << endl;
}

void test_1()
{
    
    
    for (int i = 0; i < 100; i++) {
    
    
        cout << "hello world"  << endl;
    }
}

void test_2()
{
    
    
    for (int i = 0; i < 100; i++ ){
    
    
        cout << "hello " << endl;
    }
}

int main() {
    
    

    std::cout << "Hello, World!" << std::endl;

    std::cout << "this is break" << endl;
    test_1();

    for (int i = 0; i < 20; i++) {
    
    
        test();
        cout << i << endl;
    }

    cout << "this main stop" << endl;

    return 0;
}

$ g++ -std=c++11 main.cpp -o app
$ g++ -std=c++11 main.cpp -g -o app_debug
$ ls -lh *pp*
-rwxr-xr-x 1 root root  28K 4月   7 15:38 app_debug
-rwxr-xr-x 1 root root 9.1K 4月   7 15:38 app
-rw-r--r-- 1 root root   97 4月   7 15:36 main.cpp
/* 可以发现添加了调试信息的程序比较大, 而实际的运行程序是不需要开启调试信息的 */
  • 启动gdb与查看文件
/* 启动gdb */
$ gdb app_debug

/* 查看文件 list:   l 文件名:行号(函数名)*/
$ l
 
/* 查看main.cpp文件, 20行 */
$ l main.cpp:20

/* 查看main.cpp文件, test函数 */
$ l main.cpp:test
  • 设置断点
/* 在main.cpp 19行设置断点 */
(gdb) b 19
Breakpoint 1 at 0x9a8: file main.cpp, line 19.

/* 条件断点 */
(gdb) b 12 if i == 15
Breakpoint 2 at 0x962: file main.cpp, line 12.

/* 查看断点 */
(gdb) info break
Num     Type(断点类型)           Disp Enb Address(断点是否可用)            What(断点说明)
1       breakpoint     			keep y(y可用)   							0x00000000000009a8 in test_2() at main.cpp:19
2       breakpoint     			keep y   								0x0000000000000962 in test_1() at main.cpp:12  stop only if i == 15(详细描述)
3       breakpoint     			keep y   								0x00000000000009a8 in test_2() at main.cpp:16    stop only if i == 18(详细描述)

  • gdb执行
/* 1. start */
(gdb) start

/* next 单步调试 */
(gdb) n

/*step 单步调试 —— 可以进入函数体内部 */
(gdb) s
 
/* continue, 连续运行直到遇到第一个断点  */
(gdb) c

/* s 进入函数内部 */
(gdb) s

/* l 查看函数源码 */
(gdb) l

/* 查看变量值 p 变量名 */
(gdb) p i
$1 = 0 

/* 查看变量类型 ptype 变量名 */
(gdb) ptype i
type = int

/* 追踪变量值 display i */
/* 单步调试默然这样展示调试信息 */
				29          for (int i = 0; i < 20; i++) {
    
    
				(gdb) n
				30              test();
				(gdb) n
				hello world
				31              cout << i << endl;
				(gdb) n
				14
				29          for (int i = 0; i < 20; i++) {
    
    
				(gdb) n
				30              test();
/* 使用display跟踪变量值 */
(gdb) display  i
			1: i = 16
			(gdb) n
			hello world
			31              cout << i << endl;
			1: i = 16 (这时会跟踪变量i并且打印其值 )
			(gdb) n
			16
			29          for (int i = 0; i < 20; i++) {
    
    
			1: i = 16 (这时会跟踪变量i并且打印其值 )
			(gdb) n
			30              test();
			1: i = 17 (这时会跟踪变量i并且打印其值 )
			(gdb) n
			hello world
			31              cout << i << endl;
			1: i = 17

/* 去除追踪变量 undisplay 变量编号 */
(gdb) info display (获取变量追踪信息)
	Auto-display expressions now in effect:
	Num Enb Expression
	1:   y  i
(gdb) undisplay 1 (取消追踪变量i)
(gdb) info display 
There are no auto-display expressions now.	

/* u 跳出本次循环 */
(gdb) u

/* 删除断点 */
(gdb) info break (查看断点编号)
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000555555554a7b in main() at main.cpp:28
        breakpoint already hit 1 time
(gdb) delete breakpoints 1
(gdb) info break
No breakpoints or watchpoints.

/* finish 跳出函数体, 但是要先去除函数体中断点 */
(gdb) finish

/* 设置变量值 set variable i = 10 */
(gdb) display i (为了比较直观的查看。 先跟踪i)
(gdb) set variable i = 10
(gdb) n

/* 例子 */
	(gdb) display i
	(gdb) set variable  i = 10
	(gdb) n
	10
	31          for (int i = 0; i < 20; i++) {
    
    
	1: i = 10 (从循环i=10处向后运行)
	(gdb) n
	32              test();
	1: i = 11
	(gdb) n
	hello world
	33              cout << i << endl;
	1: i = 11

/* 退出gdb quit*/
(gdb) quit

猜你喜欢

转载自blog.csdn.net/gripex/article/details/105366096