您的位置:首页 > 编程语言

使用gdb watch调试代码

2015-09-25 07:25 183 查看
  本篇文章将使用一个简单的例子说明如何使用gdb watch调试代码。

  首先来看以下一段简单的代码

       


       

  显然,第7行代码是有问题,那么这个错误的memset会造成什么后果呢?

  我们运行以下两个指令看下程序的输出:

   g++ -g main.c -o main.o

   ./main.o

  程序的输出是0 0 3,变量a的值因为memset被错误地修改了。

  因为这是个很短的程序,所以我们能很轻松地看出第7行的代码是有问题的。这里的memset会越界,错误地修改了a的值。在实际情况下,当我们发现某个变量的值不符合预期时,一般的做法是先查下这个变量的引用,找到对该变量有写操作的地方(在本例中,对变量a的写操作只有一处,即第6行)。当我们发现所有的写操作和逻辑都不会产生该非法值时,可以认定程序中有越界的情况。越界的情况在实际项目中是非常令人头痛的。一是问题的根源难以定位:在本例中异常的数据是a,但其根本原因是对b操作不当造成的。二是越界之后程序的行为是未定义的,而除了回档之外也找不到到更好的方法来还原数据。

  在开发环境下,我们可以使用gdb来辅助定位越界这一问题,这里用的是watch命令。

  我们将断点设在第7行,并运行程序。可以分别看下a,b,c的值,可以看到这个时候三个变量的值都是正常的(实际这个时候变量c的值也是未定义的,看编译器怎么处理)。我们再分别打印变量a和变量b的地址,可以看到a的地址比b大4 。(回忆下,一个int型变量占4个字节,而栈上的内存是从大到小分配的)。

      


  这个我们使用watch监控变量a值得变量,一种做法是直接watch
a,我的习惯是watch地址,watch地址的方法更加具有普适性一些。

具体的指令是 watch *(int *)0x7fff84b67b08。然后我们继续执行程序看会在哪一步停下来,

      


  程序在执行到第8行时发现watch的一段内存有变化,旧的值是1,新的值是0。这个时候我们回去看程序,就能发现是第7行这个memset错误地清空了a的内存空间。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  gdb watch 调试