在GDB中查找变量

时间:2017-02-02 05:01:14

标签: c++ debugging variables gdb

我正在一个项目中工作,其中有超过100个源代码文件。我正在调试它以找到错误。

我需要找到的是将特定对象分配给值的时间。即。这个对象起初是NULL,但是其他一些文件会更改其值,我不知道。

当此变量更改其值时,是否有任何方法可以找到?

我现在尝试的是在启动变量的函数上放置一个断点。我还添加了一个观察点。但它没有表明价值在变化的任何一点。

1 个答案:

答案 0 :(得分:2)

  

但它没有表明价值在变化的任何一点。

有两种可能的解释:

  1. 您未正确设置观察点,或
  2. 当进程处于内核模式时,值会发生变化(GDB观察点对于检测此类更改无效)。
  3. 示例:

    #include <unistd.h>
    
    int global_a;
    int global_b;
    
    int foo()
    {
      global_a = 42;
      read(0, &global_b, 1);
    
      return global_a + global_b;
    }
    
    int main()
    {
      return foo();
    }
    
    gcc -g -Wall t.c
    
    gdb -q ./a.out
    (gdb) start
    Temporary breakpoint 1 at 0x400563: file t.c, line 16.
    Starting program: /tmp/a.out
    
    Temporary breakpoint 1, main () at t.c:16
    16    return foo();
    (gdb) watch global_a
    Hardware watchpoint 2: global_a
    (gdb) watch global_b
    Hardware watchpoint 3: global_b
    (gdb) c
    Continuing.
    Hardware watchpoint 2: global_a
    
    Old value = 0
    New value = 42
    

    这是对用户空间global_a的修改(通过直接分配),它会按预期触发观察点2

    foo () at t.c:9
    9     read(0, &global_b, 1);
    (gdb) c
    Continuing.
                        # Press Enter here
    

    0xA == 10读入global_b

    [Inferior 1 (process 126196) exited with code 064]
    

    请注意,退出代码为064 == 52 == 42+10,但观察点3 开火。

      

    查找此变量何时更改其值的任何方法

    如果你确定你的&#34;正常&#34;观察点正在运行(例如,通过自己运行以上测试)并怀疑通过系统调用更改了变量,您可以:

    1. 打印变量的地址和
    2. strace下运行您的程序,并查找可能会更改变量地址值的系统调用。
    3. 使用相同的例子:

      (gdb) p &global_b
      $1 = (int *) 0x601044 <global_b>
      
      strace -e raw=all ./a.out < /dev/zero
      
      execve(0x7ffe1853e530, 0x7ffe1853f920, 0x7ffe1853f930) = 0
      brk(0)                                  = 0x2253000
      access(0x7fa66eee48c3, 0)               = -1 (errno 2)
      mmap(0, 0x2000, 0x3, 0x22, 0xffffffff, 0) = 0x7fa66f0e8000
      ...
      munmap(0x7f57ece26000, 0x203a2)         = 0
      read(0, 0x601044, 0x1)                  = 0x1  ### &global_b is "covered" by the buffer being read into
      exit_group(42)                          = ?
      +++ exited with 42 +++