调试程序
//test
2 #include<unistd.h>
3 int add(int a,int b)
4 {
5 int c = a+b;
6 return c;
7 }
8
9 int main()
10 {
11 int a=3;
(gdb) l
12 int b=5;
13 int c=add(a,b);
14 printf("c=%d\n",c);
15 return 0;
16 }
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/wangdong/Project/gdb/a...done.
(gdb) b 9 //打断点 9
Breakpoint 1 at 0x40054f: file a.c, line 9.
(gdb) run //执行
Starting program: /home/wangdong/Project/gdb/a
Breakpoint 1, main () at a.c:11
11 int a=3;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) p a // 打印 a 0
$1 = 0
(gdb) n
12 int b=5;
(gdb) p a
$2 = 3 // p a 3
(gdb) p b
$3 = 0
(gdb) n
13 int c=add(a,b);
(gdb) p b
$4 = 5 // p b 5
(gdb) s //进入函数
add (a=3, b=5) at a.c:5
5 int c = a+b;
(gdb) p c
$5 = 0
(gdb) n
6 return c;
(gdb) p c
$6 = 8 // p c 8
(gdb) p &c
$7 = (int *) 0x7fffffffe2dc //p &c
(gdb)
$8 = (int *) 0x7fffffffe2dc
(gdb) n
7 }
(gdb) n
main () at a.c:14
14 printf("c=%d\n",c);
(gdb) i b //查看断点信息
Num Type Disp Enb Address What
1 breakpoint keep y 0x000000000040054f in main
at a.c:9
breakpoint already hit 1 time
(gdb) d 1 // 删除 断点
(gdb) i b
No breakpoints or watchpoints.
(gdb) quit //退出
A debugging session is active.
Inferior 1 [process 2644] will be killed.
Quit anyway? (y or n)
过程:
1、调试的时候加上 -g
gcc -o test test.c -g
2、l 显示代码信息(list)
3、b 行号 打断点(break)
4、r 执行(run)
5、 i b (info breakpoints) 查看断点信息
6、d 断点的行号 删除断点(delete)
7、p 打印变量的值 ,变量的地址(print)
8、s 单步执行(step可以进入函数体)
9、n 单步执行 (next 不进入函数)
10、q 退出(quit)
带参数程序
调试时,与普通的程序一样;加上设置参数
1、gdb test
2、set args 192.168.1.21 8080 <设置参数>
调试多进程
//process.c
#include<stdio.h>
#include<unistd.h>
int main()
{
pid_t pid = fork();
int status;
if(pid>0)
{
wait(&status);
printf("parent pid =%d\n",getpid());
}
else if(pid == 0)
{
printf("child pid =%d\n",getpid());
}
else
{
perror("fork");
}
return 0;
}
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/wangdong/Project/gdb/pp/process...done.
(gdb) show follow-fork-mode //查看主线进程
Debugger response to a program call of fork or vfork is "parent".
(gdb) show detach-on-fork //查看是否分离
Whether gdb will detach the child of a fork is on.
(gdb) set detach-on-fork off //设置两个进程
(gdb) show detach-on-fork
Whether gdb will detach the child of a fork is off.
(gdb) i i 查看正在执行的进程
Num Description Executable
* 1 <null> /home/wangdong/Project/gdb/pp/process
(gdb) b 1
Breakpoint 1 at 0x400655: file process.c, line 1.
(gdb) r
Starting program: /home/wangdong/Project/gdb/pp/process
Breakpoint 1, main () at process.c:5
5 pid_t pid = fork(); //创建进程
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) n
[New process 3193]
7 if(pid>0)
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) i i
Num Description Executable
2 process 3193 /home/wangdong/Project/gdb/pp/process //子进程
* 1 process 3189 /home/wangdong/Project/gdb/pp/process //父进程
(gdb) inferior 2 //切换进程
[Switching to inferior 2 [process 3193] (/home/wangdong/Project/gdb/pp/process)]
[Switching to thread 2 (process 3193)]
#0 0x00007ffff7ad7291 in fork () from /lib64/libc.so.6
(gdb) n
Single stepping until exit from function fork,
which has no line number information.
main () at process.c:7
7 if(pid>0)
(gdb) n
12 else if(pid == 0)
(gdb) n
14 printf("child pid =%d\n",getpid());
(gdb) n
child pid =3193 //子进程执行结束
21 return 0;
(gdb) n
22 }
(gdb) n
0x00007ffff7a39c05 in __libc_start_main () from /lib64/libc.so.6
(gdb) n
Single stepping until exit from function __libc_start_main,
which has no line number information.
[Inferior 2 (process 3193) exited normally]
(gdb) i i
Num Description Executable
* 2 <null> /home/wangdong/Project/gdb/pp/process
1 process 3189 /home/wangdong/Project/gdb/pp/process
(gdb) inferior 1 //切换到父进程 执行结束
[Switching to inferior 1 [process 3189] (/home/wangdong/Project/gdb/pp/process)]
[Switching to thread 1 (process 3189)]
#0 main () at process.c:7
7 if(pid>0)
(gdb) n
9 wait(&status);
(gdb) n
10 printf("parent pid =%d\n",getpid());
(gdb) n
parent pid =3189
21 return 0;
(gdb) n
22 }
(gdb) n
0x00007ffff7a39c05 in __libc_start_main () from /lib64/libc.so.6
(gdb) n
Single stepping until exit from function __libc_start_main,
which has no line number information.
[Inferior 1 (process 3189) exited normally]
detach 分离
在默认情况下,在调试多进程程序时GDB只会调试主进程
过程:
1、查看正在进行的进程 info inferiors
2、切换进程 inferoir processnum
3、查看进程执行的结果 cont
调试多线程
//thread.c
#include<stdio.h>
#include<unistd.h>
#include<pthread.h>
void* fun1(void *arg)
{
int n = *(int *)arg;
printf("This is [%d] pthread\n",n);
}
void* fun(void* arg)
{
printf("This is fun \n");
}
int main()
{
pthread_t pid[5],pid1;
int i;
for(i=0;i<5;i++)
{
pthread_create(&pid[i],NULL,(void*)fun1,&i);
sleep(1);
}
pthread_create(&pid1,NULL,(void*)fun,NULL);
for(i=0;i<5;i++)
{
pthread_join(pid[i],NULL);
}
pthread_join(pid1,NULL);
return 0;
}
Breakpoint 1, fun1 (arg=0x7fffffffe2b4) at pthread.c:6
6 int n = *(int *)arg;
(gdb) n
7 printf("This is [%d] pthread\n",n);
(gdb) n
This is [1] pthread
8 }
(gdb) info threads //查看线程信息
Id Target Id Frame
* 4 Thread 0x7ffff67f9700 (LWP 3811) "pthread" 0x00007ffff78f4311 in clone ()
from /lib64/libc.so.6
3 Thread 0x7ffff6ffa700 (LWP 3810) "pthread" fun1 (arg=0x7fffffffe2b4) at pthread.c:8
2 Thread 0x7ffff77fb700 (LWP 3801) "pthread" 0x00007ffff7bc6e38 in start_thread ()
from /lib64/libpthread.so.0
1 Thread 0x7ffff7fdd740 (LWP 3800) "pthread" 0x00007ffff78f4311 in clone ()
from /lib64/libc.so.6
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/wangdong/Project/gdb/pp/pthread
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
[New Thread 0x7ffff77fb700 (LWP 3813)]
[Switching to Thread 0x7ffff77fb700 (LWP 3813)]
Breakpoint 1, fun1 (arg=0x7fffffffe2b4) at pthread.c:6
6 int n = *(int *)arg;
(gdb) info threads
Id Target Id Frame
* 2 Thread 0x7ffff77fb700 (LWP 3813) "pthread" fun1 (arg=0x7fffffffe2b4) at pthread.c:6
1 Thread 0x7ffff7fdd740 (LWP 3812) "pthread" 0x00007ffff78bb1ad in nanosleep ()
from /lib64/libc.so.6
(gdb) cont
Continuing.
This is [0] pthread
[Thread 0x7ffff77fb700 (LWP 3813) exited]
[New Thread 0x7ffff6ffa700 (LWP 3822)]
[Switching to Thread 0x7ffff6ffa700 (LWP 3822)]
Breakpoint 1, fun1 (arg=0x7fffffffe2b4) at pthread.c:6
6 int n = *(int *)arg;
(gdb) cont
Continuing.
This is [1] pthread
[Thread 0x7ffff6ffa700 (LWP 3822) exited]
[New Thread 0x7ffff67f9700 (LWP 3823)]
[Switching to Thread 0x7ffff67f9700 (LWP 3823)]
Breakpoint 1, fun1 (arg=0x7fffffffe2b4) at pthread.c:6
6 int n = *(int *)arg;
(gdb)
Continuing.
This is [3] pthread
[Thread 0x7ffff67f9700 (LWP 3823) exited]
[New Thread 0x7ffff5ff8700 (LWP 3824)]
[Switching to Thread 0x7ffff5ff8700 (LWP 3824)]
Breakpoint 1, fun1 (arg=0x7fffffffe2b4) at pthread.c:6
6 int n = *(int *)arg;
(gdb)
Continuing.
This is [3] pthread
[Thread 0x7ffff5ff8700 (LWP 3824) exited]
[New Thread 0x7ffff57f7700 (LWP 3825)]
[Switching to Thread 0x7ffff57f7700 (LWP 3825)]
Breakpoint 1, fun1 (arg=0x7fffffffe2b4) at pthread.c:6
6 int n = *(int *)arg;
(gdb)
Continuing.
This is [4] pthread
[Thread 0x7ffff57f7700 (LWP 3825) exited]
[New Thread 0x7ffff4ff6700 (LWP 3826)]
This is fun
[Thread 0x7ffff4ff6700 (LWP 3826) exited]
[Inferior 1 (process 3812) exited normally]
(gdb)
过程:
1、查看正在执行的线程
2、切换线程 thread +pthreadnum
3、cont
段错误调试
原因:
1、
#include<stdio.h>
#include<unistd.h>
void dummy_function()
{
unsigned char *ptr =0x00;
*ptr = 0x00; //访问NULL地址
}
int main()
{
dummy_function();
return 0;
}
方法一:单步调试
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) b 1
Breakpoint 1 at 0x4004f1: file test.c, line 1.
(gdb) run
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/wangdong/Project/gdb/test
Breakpoint 1, dummy_function () at test.c:5
5 unsigned char *ptr =0x00;
(gdb) n
6 *ptr = 0x00;
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x00000000004004fd in dummy_function () at test.c:6
6 *ptr = 0x00;
(gdb) where //详细查看在哪出错
#0 0x00000000004004fd in dummy_function () at test.c:6
#1 0x0000000000400510 in main () at test.c:11
方法二:快速定位(利用core文件)
@第一种情况:
1、编译时,加上 -g 执行程序,会生成一个core.*文件
2、启动GDB,利用core.*文件快速定位到”段错误“的位置
3、gdb test core.2344 进行调试
4、使用wher命令,可以快速定位到详细信息
@第二种情况
如果编译时,加上 -g,执行程序,在同级目录下没有生产core文件
core文件与当前的环境设置有关,可以使用该命令可以产生core文件
ulimit -c unlimited,继续进行调试
监视功能
监视全局变量的值
//b.c
#include<stdio.h>
#include<unistd.h>
int c ;
void fun()
{
c = 3;
}
int main()
{
int a=3;
int b=5;
c = a+b;
printf("a+b=%d\n",c);
fun();
printf("a+b=%d\n",c);
return 0;
}
Reading symbols from /home/wangdong/Project/gdb/b...done.
(gdb) watch c //监视的变量
Hardware watchpoint 1: c
(gdb) start //开始调试
Temporary breakpoint 2 at 0x400545: file b.c, line 10.
Starting program: /home/wangdong/Project/gdb/b
Temporary breakpoint 2, main () at b.c:10
10 int a=3;
Missing separate debuginfos, use: debuginfo-install glibc-2.17-196.el7.x86_64
(gdb) c
Continuing.
Hardware watchpoint 1: c //监视c
Old value = 0 //刚开始为0
New value = 8 //新值为8
main () at b.c:13
13 printf("a+b=%d\n",c);
(gdb) g
Ambiguous command "g": gcore, generate-core-file, goto-bookmark.
(gdb) c
Continuing.
a+b=8
Hardware watchpoint 1: c
Old value = 8 //开始为8
New value = 3 //新值为3
fun () at b.c:7
7 }
(gdb) n
main () at b.c:15
15 printf("a+b=%d\n",c);
(gdb) m
Ambiguous command "m": macro, maintenance, make, mem, monitor, mt.
(gdb) n
a+b=3
16 return 0;
(gdb) n
17 }