我有一个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
答案 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没有捕到这个,因为如果,例如,k
和clocklength
在堆栈上彼此相邻,那么valgrind无法判断您是否拥有对{{{ 1}}或者是k
末尾的错误访问,因为它检查的是你实际访问的内存。