简体   繁体   中英

Valgrind for C program reporting unbelievable invalid write

Anyone have problems with Valgrind incorrectly reporting an invalid write? I've got a C program with this loop:

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);
 }
}

I run Valgrind using,

valgrind --log-file=./logfile --leak-check=full ./myProgram

and the first and only "Invalid" error it lists is:

==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 states the error occurs in the line of code:

myData[bb] = variable1[ii] + jj;

If I step through the program at that point using gdb, it runs fine. The last printf displayed before the loop completes is:

ss = 687, ii = 686, bb = 2690

I can't seem to observe any problem outside of Valgrind. Valgrind consistently gives this error, but gdb consistently shows no problem.

The memory allocated for myData is, as Valgrind correctly reports, 209712 bytes, which is room for 209712/4 = 52428 integers (I'm using Linux 64 bit machine). From the printf statement, I can see the for loop exits with bb=2690 as it should. So the largest index used for array myData[bb] (where Valgrind complains) is myData[2689] .

Can anyone shed some light where I can look next? I've been staring at this all day. I've not used Valgrind much, and I don't want to call it a lier, but am I doing something wrong here? Any advice much appreciated.

UPDATE 1

The call to myfunc4() inside myfunc3() is:

int *myData, lengthA; 
...
myData = malloc( sizeof(int) * lengthA / 10); 
myfunc4(myData);

UPDATE 2

If I modify the loop to include an if (bb>10000) statement, gdb never tests true, but Valgrind does. The compiled program is the same. Anyone have any insight what's going on?

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);
 }
}

I finally figured out the bug. Malloc, of course, doesn't initialize to zero, and I had an if statement (not shown above) that set some array values, but there wasn't a else statement to catch the other path to set the same array values, so that other path used the unitialized values which led to bad behavior.

In this debugging effort, gdb did a better job initializing arrays to zero (via malloc) compared to Valgrind. Not that one should rely on that, but that appears to be the difference between results obtained with gdb and Valgrind here, at least.

Get the actual number of bytes allocated for the data and pass it to the function:

size_t szData = sizeof(int) * lengthA / 10; 
myData = malloc(szData);
myfunc4(myData, szData);

and check the access to verify valgrind:

/* .... */
assert((bb +1) * sizeof(int) < szData);
myData[bb] = variable1[ii] + jj;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM