zoukankan      html  css  js  c++  java
  • GDB调试

    主要是根据《Linux software debugging with GDB》、《用GDB调试程序》所做的笔记

    一、初步

    例子一: test.c

    #include <stdio.h>
    
    int func(int n)
    {
    	int sum=0, i;
    	for(i=1; i<=n; i++)
    	{
    		sum+=i;
    	}
    	return sum;
    }
    
    
    main()
    {
    	int i;
    	long result = 0;
    	for(i=1; i<=100; i++)
    	{
    		result += i;
    	}
    
    	printf("result[1-100] = %d 
    ", result );
    	printf("result[1-250] = %d 
    ", func(250) );
    }

     编译过程需要 -g 选项,使生成的可执行文件中包含调试信息

    gcc -g test.c -o test

    使用GDB调试:

    tree@virtual:~/shell$ gdb test
    GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
    Copyright (C) 2012 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 "i686-linux-gnu".
    For bug reporting instructions, please see:
    <http://bugs.launchpad.net/gdb-linaro/>...
    Reading symbols from /home/tree/shell/test...done.
    (gdb) l 1                  //list,显示源码
    1 #include <stdio.h>
    2
    3 int func(int n)
    4 {
    5 int sum=0, i;
    6 for(i=1; i<=n; i++)
    7 {
    8 sum+=i;
    9 }
    10 return sum;
    (gdb)                     //回车,重复上一次命令
    11 }
    12
    13
    14 main()
    15 {
    16 int i;
    17 long result = 0;
    18 for(i=1; i<=100; i++)
    19 {
    20 result += i;
    (gdb) b 16                 //break,在16行处设置断点
    Breakpoint 1 at 0x804841a: file test.c, line 16.
    (gdb) b func                //在函数入口处设置断点
    Breakpoint 2 at 0x80483ea: file test.c, line 5.
    (gdb) info b                //查看断点信息
    Num Type Disp Enb Address What
    1 breakpoint keep y 0x0804841a in main at test.c:16
    2 breakpoint keep y 0x080483ea in func at test.c:5
    (gdb) r                   //run,运行程序
    Starting program: /home/tree/shell/test

    Breakpoint 1, main () at test.c:17
    17 long result = 0;
    (gdb) n                   //next, 单步执行(next是单步步过, step是单步步入)
    18 for(i=1; i<=100; i++)
    (gdb) n
    20 result += i;
    (gdb) n
    18 for(i=1; i<=100; i++)
    (gdb) n
    20 result += i;
    (gdb) c                   //continue, 继续运行程序
    Continuing.
    result[1-100] = 5050

    Breakpoint 2, func (n=250) at test.c:5
    5 int sum=0, i;
    (gdb) n
    6 for(i=1; i<=n; i++)
    (gdb) p i                  //print, 打印变量i的值
    $1 = -1207961320
    (gdb) n
    8 sum+=i;
    (gdb) n
    6 for(i=1; i<=n; i++)
    (gdb) p sum
    $2 = 1
    (gdb) n
    8 sum+=i;
    (gdb) p i
    $3 = 2
    (gdb) n
    6 for(i=1; i<=n; i++)
    (gdb) p sum                
    $4 = 3
    (gdb) bt                 //backtrace, 查看函数堆栈
    #0 func (n=250) at test.c:6
    #1 0x08048461 in main () at test.c:24
    (gdb) finish                //退出函数
    Run till exit from #0 func (n=250) at test.c:6
    0x08048461 in main () at test.c:24
    24 printf("result[1-250] = %d ", func(250) );
    Value returned is $5 = 31375
    (gdb) c
    Continuing.
    result[1-250] = 31375
    [Inferior 1 (process 3422) exited with code 027]
    (gdb) q                   //quit,退出GDB
    tree@virtual:~/shell$

     二、断点和观察点进阶

    例子二:test2.c

    #include <stdio.h>
    
    int wib(int no1, int no2)
    {
      int result, diff;
      diff = no1 - no2;
      result = no1 / diff;
      return result;
    }
    
    int main(int argc, char *argv[])
    {
      int value, div, result, i, total;
    
      value = 10;
      div = 6;
      total = 0;
    
      for(i = 0; i < 10; i++)
      {
        result = wib(value, div);
        total += result;
        div++;
        value--;
      }
      
      printf("%d wibed by %d equals %d
    ", value, div, total);
      return 0;
    }

     条件断点

    root@virtual:/home/tree/shell# gdb test2
    GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
    Copyright (C) 2012 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 "i686-linux-gnu".
    For bug reporting instructions, please see:
    <http://bugs.launchpad.net/gdb-linaro/>...
    Reading symbols from /home/tree/shell/test2...done.
    (gdb) b 21 if value != div          //设置条件断点
    Breakpoint 1 at 0x8048437: file test2.c, line 21.
    (gdb) info b
    Num Type Disp Enb Address What
    1 breakpoint keep y 0x08048437 in main at test2.c:21
    stop only if value != div
    (gdb) condition 1 value == div        //使用condition更改在指定断点号上设置的条件
    (gdb) info b
    Num Type       Disp Enb Address    What
    1   breakpoint keep y   0x08048437 in main at test2.c:21
    stop only if value == div
    (gdb) r
    Starting program: /home/tree/shell/test2

    Breakpoint 1, main (argc=1, argv=0xbffff7c4) at test2.c:21
    21 result = wib(value, div);
    (gdb) info locals                //查看局部变量
    value = 8
    div = 8
    result = 4
    i = 2
    total = 6
    (gdb) info b
    Num Type       Disp Enb Address    What
    1   breakpoint keep y   0x08048437 in main at test2.c:21
    stop only if value == div
    breakpoint already hit 1 time

    info b查看断点信息,Enb列指定了是否启用该断点。可使用disable <b number>、enable <b number>、delete <b number>来禁用、启用和彻底删除断点

    观察点

    当指定表达式的值改变时,监视点将中断程序执行,但必须在表达式中所使用的变量在作用域中时设置监视点。

    root@virtual:/home/tree/shell# gdb test2

    GNU gdb (Ubuntu/Linaro 7.4-2012.04-0ubuntu2.1) 7.4-2012.04
    Copyright (C) 2012 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 "i686-linux-gnu".
    For bug reporting instructions, please see:
    <http://bugs.launchpad.net/gdb-linaro/>...
    Reading symbols from /home/tree/shell/test2...done.
    (gdb) b main
    Breakpoint 1 at 0x8048415: file eg1.c, line 15.
    (gdb) r
    Starting program: /home/tree/shell/test2

    Breakpoint 1, main (argc=1, argv=0xbffff7b4) at eg1.c:15
    15 value = 10;
    (gdb) watch div == value
    Hardware watchpoint 2: div == value
    (gdb) c
    Continuing.
    Hardware watchpoint 2: div == value

    Old value = 0
    New value = 1
    main (argc=1, argv=0xbffff7b4) at eg1.c:19
    19 for(i = 0; i < 10; i++)

    (gdb) i locals
    value = 8
    div = 8
    result = 4
    i = 1
    total = 6
    (gdb) i watch
    Num Type Disp Enb Address What
    2 hw watchpoint keep y div == value
    breakpoint already hit 1 time

  • 相关阅读:
    MySQL令人咋舌的隐式转换
    阿里规范中为什么要求表必须有主键id
    理解Python闭包,这应该是最好的例子
    MySQL 高级(进阶) SQL 语句精讲(二)
    什么是可串行化MVCC
    Oracle11g:数据库恢复总结
    以友盟+U-Push为例,深度解读消息推送的筛选架构解决方案应用与实践
    一万字详解 Redis Cluster Gossip 协议
    [JS]给String对象添加方法,使传入的字符串字符之间以空格分开输出
    [JS]计算字符串中出现最多的字符和其出现次数
  • 原文地址:https://www.cnblogs.com/itree/p/4776296.html
Copyright © 2011-2022 走看看