需要帮助追踪非法写入。 valgrind没有注意到它

时间:2012-01-06 07:05:42

标签: c valgrind

我有一个C程序,它被捕获在一个不应该的for循环中,用

运行它

valgrind --tool=memcheck --leak-check=yes a.out

在程序被捕获之前,

甚至不会返回任何内容。有没有办法改变valgrind的设置,以帮助我找到 leak ?正如许多人所指出的,它不会被视为泄密,道歉

提前致谢

这是有问题的循环

int clockstate=0;
int clocklength=0;
int datalength=0;
int datastate=0;
int dataloc = 9;

((((some other code that i don't think is important to this part))))

int dataerr[13] = {0};
int clockerr[13] = {0};     // assumes that spill does not change within an event.
int spill=0;
int k = 0;

spill = Getspill(d+4*255+1);                // get spill bit from around the middle
//printf("got spill: %d \n", spill);            // third breakpoint
for( k = 0; k < 512; k++)
{
    // Discardheader(d);      // doesnt actually do anything, since it's a header.f
    int databit = Getexpecteddata(d+4*k+1);
    printf("%d ",k);
    int transmitted = Datasample(&datastate, &datalength, d+4*k+2,dataerr,dataloc, databit);
    printf("%d ",k);
    Clocksample(&clockstate, &clocklength, d+4*k+3,clockerr, transmitted); 
    printf("%d \n",k);
    // assuming only one error per event (implying the possibility of multi-error "errors"
    // we construct the final error at the very end of the (outside this loop)


}

并且打印后循环重复

254 254 254

255 255 255

256 256 1&lt; - 这是问题

2 2 2

3 3 3

编辑**所以我已经跟踪了它发生的位置,以及

中的某个点

void Clocksample (int* state, int* length, char *d, int *type, int transbit);

我的代码显示*length = 1;所以看起来这个命令以某种方式写入int k。我现在的问题是,这是怎么发生的,为什么它不会像我想要的那样将length改回一个,以及如何解决它。如果你愿意,我可以将整个代码发布到Clocksample

3 个答案:

答案 0 :(得分:2)

与上次类似,这次函数之一Clocksample()正在写入不属于函数应该使用的数据/数组的内存。最有可能是一个越界数组写入。注意:这不是内存泄漏,即分配然后丢失应该释放的内存块的跟踪。

Clocksample()为256时调用k时设置断点。然后进入Clocksample(),密切关注k(或k使用的内存{1}})。您也可以在分配给k的内存上设置硬件内存写断点。你如何做到这一点取决于你正在使用的调试器。

现在是单步(如果你设置了硬件断点,则只运行到Clocksample()的返回),当k发生变化时,你就会有罪魁祸首。

答案 1 :(得分:2)

请注意,在检测堆栈缓冲区溢出时,Valgrind 非常弱(这里似乎正在发生这种情况)。

Google address-sanitizer在检测堆栈溢出方面要好得多,我建议你尝试一下。

答案 2 :(得分:1)

因此,调试输出表明在调用函数k期间Clocksample正在更改。我看到您将至少两个变量&clockstate&clocklength的地址传递给该调用。我很可能在Clocksample中有一个数组溢出或其他一些指针,最终会覆盖存储k的内存位置。

如果您发布声明k的代码(以及在同一范围内附近声明的其他变量),则可以缩小错误范围。例如,如果在clocklength之前声明k,那么您可能在使用指针值&clocklength时遇到错误,导致写入clocklength的末尾并损坏{{} 1}}。但是如果没有你正在使用的变量的实际布局,很难确定。

valgrind没有捕到这个,因为如果,例如,kclocklength在堆栈上彼此相邻,那么valgrind无法判断您是否拥有对{{{ 1}}或者是k末尾的错误访问,因为它检查的是你实际访问的内存。