功能 一般来说,GDB主要完成下面四个方面的功能: 1、启动程序,按照自定义的要求随心所欲的运行程序。 2、可让被调试的程序在指定的调试的断点处停住。(断点可以是条件表达式) 3、当程序被停住时,可以检查此时程序中所发生的事。 4、可以改变程序,将一个BUG产生的影响修正从而测试其他BUG。
一、启动调试
调试C程序时需要在编译上加上-g参数
例如:
gcc -g helloworld.c -o helloworld
可以使用以下方式判断程序是否有调试信息
1、gdb “可执行文件”
例如:
$ gdb helloworld
Reading symbols from helloworld...(no debugging symbols found)...done.
可见此例没有调试信息,如果没有调试信息,会提示 no debugging symbols found.
如果提示信息如下,则说明程序有调试信息,可以使用GDB调试
Reading symbols from helloworld...done.
2、readelf查看段信息 例如:
$ readelf -S helloworld|grep debug
[26] .debug_aranges PROGBITS 0000000000000000 0000103a
[27] .debug_info PROGBITS 0000000000000000 0000106a
[28] .debug_abbrev PROGBITS 0000000000000000 00001387
[29] .debug_line PROGBITS 0000000000000000 00001469
[30] .debug_str PROGBITS 0000000000000000 00001540
如果没有任何debug信息,则不能使用GDB调试
3、file查看strip状态
$ file helloworld
helloworld: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2,
for GNU/Linux 3.2.0, BuildID[sha1]=69ee2ac21982f82c0b782bc03b8f1443bb22b2e9, with debug_info, not stripped
从最后的not stripped 可以看出,当前可执行文件helloworld有调试信息,可以调试(有not stripped并不能说明一定能调试) 当最后是stripped时,则说明该文件的符号表信息和调试信息已经被去除,不能使用gdb调试
调试时可以在程序尚未启动之前调试,也可以在程序运行时调试
1、启动调试(无参程序)
例如:
//helloworld.c
#include <stdio.h>
int main(void)
{
printf("Hello World!\n");
return 0;
}
先编译
$ gcc -g helloworld.c -o helloworld
然后使用gdb "可执行文件名"
的方式启动调试
$ gdb helloworld
输入run命令,即可运行程序
$ run
2、启动调试(有参程序) 例如:
//helloworld.c
#include <stdio.h>
int main(int argc, char *argv[])
{
if(1 >= argc)
{
printf("Usage:./helloworld [argument]\n");
return 0;
}
else
{
printf("Hello World! %s!\n", argv[1]);
return 0;
}
}
先编译
$ gcc -g helloworld.c -o helloworld
然后使用gdb “可执行文件名”的方式启动调试
$ gdb helloworld
对于带参程序,此时如果要运行时,可采用如下两种方式:
1)、run “argument”
$ run tkly
(gdb) run tkly
Starting program: /mnt/c/Users/tkly/helloworld tkly
Hello World! tkly!
[Inferior 1 (process 7593) exited normally]
(gdb)
其中tkly为输入的参数
2)、在run之前,设置set args
$ set args tkly
(gdb) set args tkly
(gdb) run
Starting program: /mnt/c/Users/tkly/helloworld tkly
Hello World! tkly!
[Inferior 1 (process 7597) exited normally]
提前设置好参数,然后直接输入run启动调试
3、调试已经在运行的程序
先使用ps 命令找到程序对应的进程号
$ ps -ef | grep "进程名"
此时可以使用attach + 进程号的方式启动调试
$ gdb
(gdb) attach 7606
可能会有以下错误:
(gdb) attach 7606
Attaching to process 7606
Could not attach to process. If your uid matches the uid of the target
process, check the setting of /proc/sys/kernel/yama/ptrace_scope, or try
again as the root user. For more details, see /etc/sysctl.d/10-ptrace.conf
ptrace: Operation not permitted.
解决方法: 切换到root用户: 将/etc/sysctl.d/10-ptrace.conf中的
kernel.yama.ptrace_scope = 1
修改为
kernel.yama.ptrace_scope = 1
4、直接调试程序对应的ID进程
可以使用gdb program pid的方式进行调试,如:
gdb helloworld 7606
或者
gdb helloworld --pid 7606
二、设置断点
1、查看已经设置的断点
info breakpoints
2、断点设置
```c
#include
int getNum() { int num; scanf(“%d”, &num); return num; }
void printNum(int num) { printf(“%d\n”, num); }
int main() { int num; num = getNum(); printNum(num);
return 0; }