GDB调试c++程序

lee@lee-PC:~/code$ tree
.
├── bin
├── lib
└── src
    └── gdb
        └── mian.cpp
4 directories, 1 file

vim下直接在编辑界面+编译::! gcc mian.cpp -o main

using namespace std;
void Test()
{
        cout << "test function" << endl;;
}
int main(int argc,char *argv[])
{
        cout << "hello gdb" << endl;
        Test();
        cout << "gdb end" << endl;
        return 0;
}
~                                                                                                             
:!g++ main.cpp -o main 

GDB常用指令;

lbirpnsc

命令格式作用
list<行号>|<函数名>查看指定位置的程序源代码
break<行号>|<函数名> |<条件表达式>设置断点
delete <断点号> |<断点范围>断点的删除
lear删除所在行的过个断点
info break显示断点信息
run运行程序
print <表达式>|<变量>查看程序运行时对应表达式和变量的值
next单步恢复程序运行,但不进入函数调用
step单步恢复程序运行,且进入函数调用
continue继续执行函数,知道函数结束或者遇到新的断点

指令:list

lee@lee-PC:~/code/src/gdb$ g++ main.cpp -o main
lee@lee-PC:~/code/src/gdb$ ls
main  main.cpp
lee@lee-PC:~/code/src/gdb$ ./main 
hello gdb
test function
gdb end
lee@lee-PC:~/code/src/gdb$ gdb main
GNU gdb (Debian 8.2.1-2+b1) 8.2.1
Copyright (C) 2018 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...(no debugging symbols found)...done.
(gdb) l
No symbol table is loaded.  Use the "file" command.
(gdb) 

执行一下指令

g++ main.cpp -o main ->
gdb main ->
l

以上list(l)没有符号表被载入,是什么原因?
因为编译的时候需要指定Debug 还是Release,是否需要把调试信息编译进去,g++默认的时候调试信息不会被编译进去
-g会把代码编译进去,把代码与二进制之间的关系编译进去,这样二进制指令执行到哪一行,同时也知道执行的代码到哪一行

g++ main.cpp -o main -g ->
gdb main ->
l

以上操作,l指令的时候才会显示出代码,一直l就会显示完所有的代码:

lee@lee-PC:~/code/src/gdb$ g++ main.cpp -o main -g
lee@lee-PC:~/code/src/gdb$ gdb main 
GNU gdb (Debian 8.2.1-2+b1) 8.2.1
Copyright (C) 2018 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/>.

--Type <RET> for more, q to quit, c to continue without paging--
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from main...done.
(gdb) l
1       #include <iostream>                                                                                   
2       using namespace std;                                                                                  
3       void Test()                                                                                           
4       {                                                                                                     
5               cout << "test function" << endl;;                                                             
6       }                                                                                                     
7       int main(int argc,char *argv[])                                                                       
8       {                                                                                                     
9               cout << "hello gdb" << endl;                                                                  
10              Test();                                                                                       
(gdb)  

list后面跟函数名:

(gdb) list Test                                                                                               
1       #include <iostream>                                                                                   
2       using namespace std;                                                                                  
3       void Test()                                                                                           
4       {                                                                                                     
5               cout << "test function" << endl;;                                                             
6       }                                                                                                     
7       int main(int argc,char *argv[])                                                                       
8       {                                                                                                     
9               cout << "hello gdb" << endl;                                                                  
10              Test();                                                                                       
(gdb)  

list后面跟行号:

(gdb) list 3                                                                                                  
1       #include <iostream>                                                                                   
2       using namespace std;                                                                                  
3       void Test()                                                                                           
4       {                                                                                                     
5               cout << "test function" << endl;;
6       }
7       int main(int argc,char *argv[])
8       {
9               cout << "hello gdb" << endl;
10              Test();
(gdb) 

指令:break,设置断点,指定到设置断点之前

  • 接行号
(gdb) break 5
Breakpoint 1 at 0x401176: file main.cpp, line 5.
(gdb) break 10
Breakpoint 2 at 0x4011c0: file main.cpp, line 10.
(gdb) break 11
Breakpoint 3 at 0x4011c5: file main.cpp, line 11.
(gdb) info b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401176 in Test() at main.cpp:5
2       breakpoint     keep y   0x00000000004011c0 in main(int, char**) at main.cpp:10
3       breakpoint     keep y   0x00000000004011c5 in main(int, char**) at main.cpp:11
  • 接函数名(函数的入口设置断点)
(gdb) break Test
Note: breakpoint 1 also set at pc 0x401176.
Breakpoint 4 at 0x401176: file main.cpp, line 5.
(gdb) info break
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0x0000000000401176 in Test() at main.cpp:5
2       breakpoint     keep y   0x00000000004011c0 in main(int, char**) at main.cpp:10
3       breakpoint     keep y   0x00000000004011c5 in main(int, char**) at main.cpp:11
4       breakpoint     keep y   0x0000000000401176 in Test() at main.cpp:5

指令:delete,删除断点:

(gdb) delete 5
No breakpoint number 5.
(gdb) delete 1
(gdb) info break
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x00000000004011c0 in main(int, char**) at main.cpp:10
3       breakpoint     keep y   0x00000000004011c5 in main(int, char**) at main.cpp:11
4       breakpoint     keep y   0x0000000000401176 in Test() at main.cpp:5

指令:run,程序运行到第一个断点处停止,此处位函数入口的断点,可以跳过(next),可以进入(step)

(gdb) run
Starting program: /home/lee/code/src/gdb/main 
hello gdb

Breakpoint 2, main (argc=1, argv=0x7fffffffcc18) at main.cpp:10
10              Test();
(gdb) 

指令:next,执行下一行代码,执行完函数,但不进入函数

指令:step,执行到函数的第一行代码

(gdb) next

Breakpoint 4, Test () at main.cpp:5
5               cout << "test function" << endl;;
(gdb) d 4
(gdb) step
test function
6       }
(gdb) 

从结果中看出,在到达函数调用处的代码时,如果函数中设置断点,next的时候会直接进入到函数代码;如果删除断点,step才会进入到函数否则,使用next就是直接执行完此处函数(当成一行代码)

指令:continue,从一个断点到下一个断点

Breakpoint 2, main (argc=1, argv=0x7fffffffcc18) at main.cpp:10
10              Test();
(gdb) continue
Continuing.
test function

Breakpoint 3, main (argc=1, argv=0x7fffffffcc18) at main.cpp:11
11              cout << "gdb end" << endl;
(gdb) 

指令print、set,打印或者设置变量的值

(gdb) l
1       #include <iostream>
2       using namespace std;
3       void Test()
4       {
5               cout << "test function" << endl;;
6       }
7       int main(int argc,char *argv[])
8       {
9               int i = 10086;
10              i++;
(gdb) 
11              cout << "hello gdb" << endl;
12              Test();
13              cout << "gdb end" << endl;
14              cout << i << endl;
15              return 0;
16      }
(gdb) 
Line number 17 out of range; main.cpp has 16 lines.
(gdb) 
Line number 17 out of range; main.cpp has 16 lines.
(gdb) break 11 
Breakpoint 1 at 0x4011bf: file main.cpp, line 11.
(gdb) break 14
Breakpoint 2 at 0x4011fc: file main.cpp, line 14.
(gdb) run
Starting program: /home/lee/code/src/gdb/main 

Breakpoint 1, main (argc=1, argv=0x7fffffffcc18) at main.cpp:11
11              cout << "hello gdb" << endl;
(gdb) print i
$1 = 10087
(gdb) set i=99
Ambiguous set command "i=99": .//`这里与内部变量冲突,需要明确指定为程序的普通变量`
(gdb) set var i=99
(gdb) c
Continuing.
hello gdb
test function
gdb end

Breakpoint 2, main (argc=1, argv=0x7fffffffcc18) at main.cpp:14
14              cout << i << endl;
(gdb) print i
$2 = 99
(gdb) c
Continuing.
99
[Inferior 1 (process 21697) exited normally]

指令:bt 查看函数调用的栈空间信息,当程序宕掉后,可以通过bt命令查看程序是从哪里宕掉的。

修改代码如下:

#include <iostream>
using namespace std;
void Test()
{
        cout << "test function" << endl;;
}
int main(int argc,char *argv[])
{
        char *str = "s=hello";
        int i = 10086;
        i++;
        cout << "hello gdb" << endl;
        Test();
        cout << "gdb end" << endl;
        str[1] = 'z';//修改常量的值
        cout << i << endl;
        return 0;
}

编译->(输出警告信息)->运行->(输出段错误)->执行gdb调试:

lee@lee-PC:~/code/src/gdb$ g++ main.cpp -o main -g
main.cpp: In function ‘int main(int, char**)’:
main.cpp:9:14: warning: ISO C++ forbids converting a string constant to ‘char*’ [-Wwrite-strings]
  char *str = "s=hello";
              ^~~~~~~~~
lee@lee-PC:~/code/src/gdb$ ./main 
hello gdb
test function
gdb end
段错误 (核心已转储)
lee@lee-PC:~/code/src/gdb$ gdb main 
(gdb) run
Starting program: /home/lee/code/src/gdb/main 
hello gdb
test function
gdb end

Program received signal SIGSEGV, Segmentation fault.
main (argc=1, argv=0x7fffffffcc18) at main.cpp:15
15              str[1] = 'z';//修改常量的值
(gdb) bt
#0  main (argc=1, argv=0x7fffffffcc18) at main.cpp:15

//-----------------------------------------------------------------------
其他知识点:window共享出来的目录是 nobody nogroup
chmod 777 * -R,当前目录下所有文件及其子文件的权限设置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值