使用valgrind和gdb跟踪变量更改

时间:2012-07-17 06:44:24

标签: c memory-leaks gdb valgrind

我有一个程序,SIGABRT执行后> 5小时。这很可能是由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 terminal,

  

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

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

> 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 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:1)

来自GDB中的help break

(gdb) help break
Set breakpoint at specified line or function.
break [LOCATION] [thread THREADNUM] [if CONDITION]
LOCATION may be a line number, function name, or "*" and an address.
If a line number is specified, break at start of code for that line.
If a function is specified, break at start of code for that function.
If an address is specified, break at that exact address.
With no LOCATION, uses current execution address of selected stack frame.
This is useful for breaking on return to a stack frame.

THREADNUM is the number from "info threads".
CONDITION is a boolean expression.

Multiple breakpoints at one place are permitted, and useful if conditional.

Do "help breakpoints" for info on other commands dealing with breakpoints.

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

答案 2 :(得分:0)

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

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

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

b)我不确定这个。你想在哪里检查'p'的价值?

答案 3 :(得分:0)

关于第一个问题,如何跟踪变量'a'中的值变化? 请使用“手表”,

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

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

      (gdb) watch foo

Joachim Pileborg得到了你的第二个问题的答案。

对于第三个问题,您需要在

行设置中断
 p->data = (stdata*) malloc (sizeof(stdata));

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