一、基本概念
GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具。或许,各位比较喜欢那种图形界面方式的,像VC、BCB等IDE的调试,但如果你是在UNIX平台下做软件,你会发现GDB这个调试工具有比VC、BCB的图形化调试器更强大的功能。所谓“寸有所长,尺有所短”就是这个道理。
二、主要功能
1、启动程序,可以按照你的自定义的要求随心所欲的运行程序。
2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
3、当程序被停住时,可以检查此时你的程序中所发生的事。
4、动态的改变你程序的执行环境。
三、GDB的基本指令
四、GDB调试多线程
测试代码:
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
#include<unistd.h>
#include<sys/types.h>
void* thread1_run(void* arg)
{
printf("thread one is running~ ! pid : %d , tid : %u\n",getpid(), pthread_self());
pthread_exit((void*)1);
}
void* thread2_run(void* arg)
{
printf("thread two is running~ ! pid : %d , tid : %u\n",getpid(), pthread_self());
pthread_exit((void*)2);
}
int main()
{
pthread_t t1,t2;
pthread_create(&t1,NULL,&thread1_run,NULL);
pthread_create(&t2,NULL,&thread2_run,NULL);
void* ret1 = NULL;
void* ret2 = NULL;
pthread_join(t1,&ret1);
pthread_join(t2,&ret2);
printf("ret1 is :d\n",ret1);
printf("ret2 is :d\n",ret2);
return 0;
}
五、1. gdb进行调试
五、2. GDB调试多进程
在默认情况下是调试多进程程序时GDB会默认调试主进程,但是GDB支持多进程的分步与同步调试。即GDB支持同时调试多个进程,只需要设置follow-fork-mode(默认为parent)和detach-on-fork(默认为on)即可。我们还可以使用catch fork-指令,如果fork异常,会停止程序。
设置方法:
set follow-fork-mode[parent|child]
set detach-on-fork[on|off]
显示:
show follow-fork-mode
show detach-on-fork
测试代码:
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{
printf("restart\n");
pid_t pid = fork();
if(pid == 0)
{
printf("child --> pid : %d , ppid : %d\n",getpid(),getppid());
sleep(1);
}
else
{
printf("father --> pid : %d , ppid : %d\n",getpid(),getppid());
sleep(1);
}
return 0;
}
只调试父进程
只调试子进程
同时进行调试(让父进程运行调试,子进程阻塞等待)
六、core文件
6.1、基本概念
在一个程序崩溃时,它一般会在指定目录下生成一个core文件。core文件仅仅是一个内存映象(同时加上调试信息),主要是用来调试的。
6.2、gdb分析core文件
1、core文件的存储路径。
通常是在执行程序的时候会出现段错误。但是在当前的目录下面没有coredump文件。可以通过如下命令查看core文件的存在位置
cat /proc/sys/kernel/core_pattern
更改coredump文件的存储位置
echo "/data/coredump/core">/proc/sys/kernel/core_pattern
设置core文件的名字让我们清楚知道是哪一个程序的core错误
echo "/data/coredump/core.%e.%p">/proc/sys/kernel/core_pattern
这样的core会自导崩溃的程序代码和进程ID
2、产生core的条件
有的时候需要确认当前的绘画能够生成coredump文件的大小。大小为0则不会生成对应的coredump文件。
通过ulimit -c
可以查看coredump文件大小的最大值
通过ulimit -c unlimited
设置core文件不受限制。如果需要指定大小则ulimit -c size
但是只是对当前的会话有作用
3、gdb定位coredump文件 非法访问内存
#include <stdio.h>
int main()
{
int b = 1;
int *a;
*a = b;
return 0;
}
查看coredump文件的ELF头部
readelf -h core… 发现文件格式为CORE说明是core-dump文件
执行gdb test core可以发现程序第5行a=b 然后分别打印a和b的值 返现指向的地址为非法区域。也就是没有分配内存导致。