2

我有一个程序在执行 > 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=yes --日志文件=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
4

4 回答 4

3
  1. 要跟踪变量值的变化,您可以在该变量上设置观察点。

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

  2. 要在所需条件下中断,您可以使用 breakbreak if loop_counter==428

于 2012-07-17T09:01:05.267 回答
1

help breakGDB 中:

(gdb) 帮助破解
在指定的行或函数处设置断点。
中断 [位置] [线程 THREADNUM] [如果条件]
LOCATION 可以是行号、函数名或“*”和地址。
如果指定了行号,则在该行的代码开始处中断。
如果指定了函数,则在该函数的代码开始处中断。
如果指定了地址,则在该确切地址处中断。
如果没有 LOCATION,则使用所选堆栈帧的当前执行地址。
这对于在返回堆栈帧时中断很有用。

THREADNUM 是来自“信息线程”的数字。
CONDITION 是一个布尔表达式。

允许在一个地方设置多个断点,如果有条件的话很有用。

执行“帮助断点”以获取有关处理断点的其他命令的信息。

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

于 2012-07-17T08:51:04.353 回答
0

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

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

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

      (gdb) watch foo

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

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

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

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

于 2012-07-17T08:56:10.263 回答
0

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

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

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

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

于 2012-07-17T08:15:16.220 回答