GDB(程序调试、带参数程序、多进程、多线程、段错误、监视功能)

调试程序

//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  }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值