![](/img/trans.png)
[英]Valgrind reporting an invalid read (and write) but the program keeps his execution
[英]Valgrind for C program reporting unbelievable invalid write
任何人都有Valgrind错误报告无效写入的问题? 我有一个带有这个循环的C程序:
void myfunc4(int *myData, ...)
{
int *variable1, *variable2, ii, ss, bb, jj;
...
bb = 0;
for (ii=0; ii<ss; ii++) {
for (jj=0; jj<(variable2[ii]-variable1[ii]+1); jj++) {
myData[bb] = variable1[ii] + jj; /* valgrind reports error is on this line */
bb = bb+1;
}
printf("ss = %d, ii = %d, bb = %d \n", ss, ii, bb);
}
}
我用Valgrind跑,
valgrind --log-file=./logfile --leak-check=full ./myProgram
它列出的第一个也是唯一的“无效”错误是:
==6135== Invalid write of size 4
==6135== at 0x4090AA: myfunc4 (myfunc4.c:170)
==6135== by 0x408527: myfunc3 (myfunc3.c:168)
==6135== by 0x406CA1: myfunc2 (myfunc2.c:84)
==6135== by 0x410163: myfunc1 (myfunc1.c:133)
==6135== by 0x413726: main (myProgram.c:511)
==6135== Address 0x1077c250 is 209,712 bytes inside a block of size 209,715 alloc'd
==6135== at 0x4A05FDE: malloc (vg_replace_malloc.c:236)
==6135== by 0x408248: myfunc3 (myfunc3.c:119)
==6135== by 0x406CA1: myfunc2 (myfunc2.c:84)
==6135== by 0x410163: myfunc1 (myfunc1.c:133)
==6135== by 0x413726: main (myProgram.c:511)
==6135==
==6135== More than 10000000 total errors detected. I'm not reporting any more.
==6135== Final error counts will be inaccurate. Go fix your program!
Valgrind声明错误发生在代码行中:
myData[bb] = variable1[ii] + jj;
如果我使用gdb在那一步完成程序,它运行正常。 循环完成之前显示的最后一个printf是:
ss = 687, ii = 686, bb = 2690
我似乎无法观察到Valgrind以外的任何问题。 Valgrind一直给出这个错误,但gdb始终没有问题。
正如Valgrind正确报告的那样,为myData
分配的内存是209712字节,这是209712/4 = 52428整数的空间(我使用的是Linux 64位机器)。 从printf
语句中,我可以看到for循环以bb = 2690退出。 所以用于数组myData[bb]
的最大索引(Valgrind抱怨)是myData[2689]
。
任何人都可以在我可以看到的地方找到一些亮点? 我一整天都在盯着这个。 我没有多多使用Valgrind,我不想把它称为lier,但我在这里做错了吗? 任何建议都非常感谢。
更新1
要将呼叫myfunc4()
内myfunc3()
是:
int *myData, lengthA;
...
myData = malloc( sizeof(int) * lengthA / 10);
myfunc4(myData);
更新2
如果我修改循环以包含if (bb>10000)
语句,gdb永远不会测试true,但是Valgrind会这样做。 编译后的程序是一样的。 任何人都有任何洞察力发生了什么?
void myfunc4(int *myData, ...)
{
int *variable1, *variable2, ii, ss, bb, jj;
...
bb = 0;
for (ii=0; ii<ss; ii++) {
for (jj=0; jj<(variable2[ii]-variable1[ii]+1); jj++) {
myData[bb] = variable1[ii] + jj;
bb = bb+1;
if (bb>10000) {
printf("bb=%d \n", bb); /* valgrind executes this line but gdb does not */
exit(1);
}
}
printf("ss = %d, ii = %d, bb = %d \n", ss, ii, bb);
}
}
我终于找到了这个bug。 当然,Malloc没有初始化为零,我有一个if
语句(上面没有显示)设置了一些数组值,但是没有else
语句来捕获另一个路径来设置相同的数组值,所以其他路径使用了导致不良行为的单一化值。
在这个调试工作中,与Valgrind相比,gdb在将数组初始化为零(通过malloc)方面做得更好。 不应该依赖于那个,但这似乎是至少在gdb和Valgrind获得的结果之间的差异。
获取为数据分配的实际字节数并将其传递给函数:
size_t szData = sizeof(int) * lengthA / 10;
myData = malloc(szData);
myfunc4(myData, szData);
并检查访问以验证valgrind:
/* .... */
assert((bb +1) * sizeof(int) < szData);
myData[bb] = variable1[ii] + jj;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.