GDB工具能对程序进程调试,用起来非常方便,这里总结gdb工具使用的方法。
- 生成带有调试信息的可执行文件
一般使用gcc或者g++生成可执行文件(包括so文件等)时,加上-g就可以了,-g能够把源代码的信息比如行号对应起来,这样后续调试的时候就知道出问题代码的具体位置了。比如新建一个程序main.cpp
#include <iostream>
#include <stdlib.h>
#include <cstring>
#include <unistd.h>
using namespace std;
typedef struct OtherInfo {
bool isMarried;
bool isStudent;
string address;
} OtherInfo;
typedef struct UserInfo {
char name[20];
int age;
char gender;
OtherInfo otherInfo;
} UserInfo;
int main()
{
UserInfo Peter{"Peter", 23, 'M', {true, false, "Canada"}};
while (true) {
cout << "hello world"<<endl;
sleep(1);
}
return 0;
}
上面的代码只是声明了相关结构体并赋值,现在用g++生成可执行文件。
g++ -std=c++11 -g -o testMain main.cpp
上面指定使用c++11,并且有-g带入调试信息生成了可执行文件testMain.
- gdb 加载可执行文件
有两个方法加载可执行文件,一个是gdb后面直接写可执行文件的名字,另一个是先进入gdb程序,使用file指令加载可执行文件。
1) 方法1
输入
gdb testMain
得到的结果如下:
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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 testMain...done.
(gdb)
上图已经成功加载了testMain这个可执行文件
2)方法2
输入gdb后用file指令加载可执行文件
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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".
(gdb) file testMain
Reading symbols from testMain...done.
(gdb)
- gdb调试正在运行的进程
有时候想要调试的进程已经在运行了,这个时候可以通过gdb attach 进程pid或者gdb - 进程pid的方法调试这个可执行文件。
比如运行上面的可执行文件testMain
输入:
./testMain
现在有一个testMain进程在运行了,这个进程在终端不断打印hello world。现在如果想要调试这个进程的话首先找到这个进程的pid。
开启另一个终端,输入:
ps axuf|grep testMain|grep -v grep|awk {'print $2'}
输出得到:
6557
这个就是进程的pid。
使用gdb attach 进程pid的方法调试进程,输入
gdb attach 6557
结果可能报如下错误(若无错误更好)。
For help, type "help".
Type "apropos word" to search for commands related to "word"...
-: 没有那个文件或目录.
Attaching to process 6432
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: 不允许的操作.
切到root用户并修改文件/etc/sysctl.d/10-ptrace.conf中的kernel.yama.ptrace_scope = 1为kernel.yama.ptrace_scope = 0
使用gdb attach 进程pid的方法调试进程。
sudo gdb attach 6557
输出结果:
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 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"...
attach: 没有那个文件或目录.
Attaching to process 6557
Reading symbols from /home/aitian/at/test/testMain...(no debugging symbols found)...done.
Reading symbols from /usr/lib/x86_64-linux-gnu/libstdc++.so.6...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libgcc_s.so.1...(no debugging symbols found)...done.
Reading symbols from /lib/x86_64-linux-gnu/libc.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libc-2.23.so...done.
done.
Reading symbols from /lib/x86_64-linux-gnu/libm.so.6...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/libm-2.23.so...done.
done.
Reading symbols from /lib64/ld-linux-x86-64.so.2...Reading symbols from /usr/lib/debug//lib/x86_64-linux-gnu/ld-2.23.so...done.
done.
0x00007f7b6747a2f0 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:84
84 ../sysdeps/unix/syscall-template.S: 没有那个文件或目录.
(gdb) c
Continuing.
还有一种简单的方法是输入
sudo gdb - 6557
两种方法的结果是一样的。
- 最常用指令:
下断点(b);单步运行n(跳过函数); 单步运行s(进入函数);继续(c);停止(ctrl+c);打印变量(p)。