【问题标题】:trace variable change using valgrind and gdb使用 valgrind 和 gdb 跟踪变量更改
【发布时间】:2012-07-16 01:34:50
【问题描述】:

我有一个程序在执行 >5 小时后发出 SIGABRT。这很可能是由 valgrind 检查后的内存泄漏引起的,但我有问题根据 valgrind 报告(仅包含地址和???)追查到哪个变量实际导致了此问题。

我尝试使用 valgrind 和 gdb 来逐步完成。但是,由于需要 5 小时才能到达泄漏点(循环 428 轮之后),我想设置一个断点,比如说,当 loop=428 时,然后进入代码。我该怎么做?

根据下面的一个简单程序,请问一下,

a) 如何追踪变量 'a' 的值变化?

b) loop = 428时如何设置断点?


typedef struct data_attr {
   int a[2500];
}stdata;

typedef struct pcfg{
    stdata *data;
}stConfig;

int funcA(stConfig* pt){  

    int loop = 0;

    while (loop < NUM_NODE){  
        pt->data->a[0] = 1000;
        pt->data->a[0] = 1001;
        loop++;
    }
    return 0;
}

int main(){
    stConfig *p;

    p = (stConfig*) malloc(sizeof(stConfig));
    p->data = (stdata*) malloc (sizeof(stdata));

    funcA(p);

    free(p->data);
    free (p);

    return 0;
}

我在 ubuntu 10.04 上使用 valgrind 3.7

@valgrind 终端,

valgrind -v --vgdb=yes --vgdb-error=0 --tool=memcheck --leak-check=full --leak-resolution=high --num-callers=40 --track-origins=是 --log-file=mr3m1n2500_valgrind_0717_1155.txt ./pt m >& mr3m1n2500_logcheck_0717_1155.txt

@gdb 终端 我试图获取 'p' 的地址,但它返回 void,为什么?

> gdb ./pt
(gdb) target remote | vgdb
Remote debugging using | vgdb
relaying data between gdb and process 12857
Reading symbols from /lib/ld-linux.so.2...Reading symbols from /usr/lib/debug/lib/ld-2.11.1.so...done.
done.
Loaded symbols for /lib/ld-linux.so.2
[Switching to Thread 12857]
0x04000850 in _start () from /lib/ld-linux.so.2
(gdb) p $p
$1 = void
(gdb) bt 10
#0  0x04000850 in _start () from /lib/ld-linux.so.2

【问题讨论】:

    标签: c memory-leaks gdb valgrind


    【解决方案1】:
    1. 要跟踪变量值的变化,您可以在该变量上设置观察点。

      对于您的情况,请使用:watch p-&gt;data-&gt;a[index]

    2. 要在需要的条件下中断,可以使用 break break if loop_counter==428

    【讨论】:

      【解决方案2】:

      来自 GDB 中的help break

      (gdb) 帮助破解 在指定的行或函数处设置断点。 中断 [位置] [线程 THREADNUM] [如果条件] LOCATION 可以是行号、函数名或“*”和地址。 如果指定了行号,则在该行的代码开始处中断。 如果指定了函数,则在该函数的代码开始处中断。 如果指定了地址,则在该确切地址处中断。 如果没有 LOCATION,则使用所选堆栈帧的当前执行地址。 这对于在返回堆栈帧时中断很有用。 THREADNUM 是来自“信息线程”的数字。 CONDITION 是一个布尔表达式。 允许在一个地方设置多个断点,如果有条件的话很有用。 执行“帮助断点”以获取有关处理断点的其他命令的信息。

      要在条件上设置断点,请使用 break if condition,在您的情况下使用 break if loop_counter == 428 或类似名称。

      【讨论】:

      • 我什至不知道这件事。谢谢!
      【解决方案3】:

      a) 如果可以执行以下操作,则设置该循环的断点:

      if(loop == 428)
          int nop = 0;
      

      然后为 int nop = 0 行设置断点。像这样,程序仅在执行该行时才停止,这发生在循环 428 中。

      b) 我不确定这个。您在哪里尝试检查“p”的值?

      【讨论】:

        【解决方案4】:

        对于您的第一个问题,如何跟踪变量“a”中值的变化? 请用“看”,

        watch [-l|-location] expr [thread threadnum] [mask maskvalue]
        

        为表达式设置观察点。当程序写入表达式 expr 并且其值发生变化时,gdb 将中断。该命令最简单(也是最流行)的用法是查看单个变量的值:

              (gdb) watch foo
        

        Joachim Pileborg 有你第二个问题的答案。

        对于第三个问题,您需要在该行设置一个中断

         p->data = (stdata*) malloc (sizeof(stdata));
        

        然后尝试打印“p”的值。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2020-07-05
          • 2021-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多