今天要分享给大家的是gdb动态调试( 动态调试就是在不终止正在运行的进程的情况下,来对这个正在运行的进程进行调试,我一般习惯称之为在线调试 )在平时开发Linux应用程序时,不管是桌面Linux应用开发,还是嵌入式Linux应用开发,在我们接到新需求开始撸代码的时候(一般这时候都是在公司编码测试,可以运行带调试信息的debug版程序),都可以使用该技能进行代码的调测,简单实用。
为了给大家演示方便,我简单写了个测试程序,代码如下:
#include < stdio.h >
#include < pthread.h >
typedef struct
{
int a;
char b;
char *c;
} TEST;
int data;
TEST test;
int fun(void)
{
printf("global variable data = %dn", data);
}
int fun2(int val)
{
data = val;
printf("set global variable data = %dn", data);
}
void *thread()
{
while(1)
{
//printf("thread is runningn");
sleep(1);
}
}
int main(int argc, char *argv[])
{
pthread_t tid;
data = 100;
test.a = 10;
test.b = 'a';
test.c = "hello world";
pthread_create(&tid, NULL, thread, NULL);
pause();
return 1;
}
为了不让程序自动结束,我创建了一个线程,然后使用如下命令进行编译,生成带调试信息的可执行程序文件。
gcc -g -o main main.c -lpthread
使用&符号,让程序在后台运行,记下程序的进程号PID(或者使用ps -e | grep main命令查询):
gdb动态调试有多种使用方式,感兴趣的小伙伴可以直接找度娘搜索下,下面是最常用的一种方式:
gdb < 可执行程序名 > < 进程ID >
比如:gdb < 可执行程序名 > 1234
这条命令会把进程ID为1234的进程与gdb联系起来,也就是说,这条命令会把进程ID为1234的进程的地址空间附着在gdb的地址空间中,然后使这个进程在gdb的环境下运行,这样的话,gdb就可以清楚地了解该进程的执行情况、函数堆栈、内存使用情况等等。
从上面我们查到main进程的PID为21310,直接执行gdb main 21310即可开启main进程的动态调试。
这时候我们借助强大的gdb可以做的事情就非常多了:
编译x86电脑上用的gdb
cd /home/tools/gdb/gdb-8.2
mkdir build
cd build
../configure --prefix=/home/tools/gdb/gdb_install_x86/
make && make install
编译arm终端上用的gdb(需要交叉编译,交叉编译工具链换成对应的即可)
cd /home/tools/gdb/gdb-8.2
mkdir build
cd build
../configure --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc CPP=arm-linux-gnueabihf-cpp CXX=arm-linux-gnueabihf-g++ --prefix=/home/tools/gdb/gdb_install_arm/
make && make install
另外,如果感觉生成的gdb可执行程序文件比较大(默认是带着调试信息的),可以用strip命令裁剪下即可,不影响使用!
好了,今天就先写到这吧,gdb动态调试在不打断程序运行的情况下,进行在线调测还是很有用的,一般在排查问题、动态改变程序执行逻辑、单元/集成测试等都可以使用,用起来非常的香!
全部0条评论
快来发表一下你的评论吧 !