When I run the Valgrind memcheck I often get many hundreds of thousands (or more, because Valgrind shuts down at 100K) of small invalid read instructions, for example:
==32027== Invalid read of size 1 ==32027== at 0x3AB426E26A: _IO_default_xsputn (in /lib64/libc-2.5.so) ==32027== by 0x3AB426CF70: _IO_file_xsputn@ @GLIBC_2.2.5 (in /lib64/libc-2.5.so) ==32027== by 0x3AB42621FA: fwrite (in /lib64/libc-2.5.so) ==32027== by 0x4018CA: STARCH_gzip_deflate (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch) ==32027== by 0x401F48: compressFileWithGzip (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch) ==32027== by 0x4028B5: transformInput (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch) ==32027== by 0x402F12: main (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch) ==32027== Address 0x7febb9b3c is on thread 1 stack
These statements relate to function calls outside of my application (" starch ") and which appear to be part of libc . Does it need to worry?
EDIT
If I modify the fwrite call to delete one byte, then my gzip stream will be corrupted. Here is the source code:
int STARCH_gzip_deflate(FILE *source, FILE *dest, int level) { int ret, flush; unsigned have; z_stream strm; unsigned char in[STARCH_Z_CHUNK]; unsigned char out[STARCH_Z_CHUNK]; strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit2(&strm, level, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); if (ret != Z_OK) return ret; do { strm.avail_in = fread(in, 1, STARCH_Z_CHUNK, source); if (ferror(source)) { (void)deflateEnd(&strm); return Z_ERRNO; } flush = feof(source) ? Z_FINISH : Z_NO_FLUSH; strm.next_in = in; do { strm.avail_out = STARCH_Z_CHUNK; strm.next_out = out; ret = deflate(&strm, flush); assert(ret != Z_STREAM_ERROR); have = STARCH_Z_CHUNK - strm.avail_out; if (fwrite(out, 1, have, dest) != have || ferror(dest)) { (void)deflateEnd(&strm); return Z_ERRNO; } } while (strm.avail_out == 0); assert(strm.avail_in == 0); } while (flush != Z_FINISH); assert(ret == Z_STREAM_END); (void)deflateEnd(&strm); return Z_OK; }
EDIT 2
I think I see a problem. I have in[STARCH_Z_CHUNK] , not in[STARCH_Z_CHUNK + 1] (and also for out[] ). If I set both the fread and fwrite statements to -1 , I don't seem to get these Invalid read of size 1 statements, although I still see a lot of Invalid read of size 4 and 8 , which are zlib specific:
==32624== Invalid read of size 4 ==32624== at 0x3AB5206455: deflateInit2_ (in /usr/lib64/libz.so.1.2.3) ==32624== by 0x40180E: STARCH_gzip_deflate (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch) ==32624== by 0x401F48: compressFileWithGzip (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch) ==32624== by 0x402C03: transformInput (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch) ==32624== by 0x402F12: main (in /home/areynolds/trunk/utility/applications/bed/starch/bin/starch) ==32624== Address 0x7feafde38 is on thread 1 stack
EDIT 3
I recompile with -g , which, as already mentioned, associates line numbers with errors.
But I'm just doing simple strncpy variables from argv[] , for example:
strncpy(uniqTag, argv[2], strlen(argv[2]) + 1);
This should copy the zero-terminated argv[2] line to uniqTag , but valgrind marks this as an error.
EDIT 4
This is where the error message appears:
==3682== Invalid read of size 1 ==3682== at 0x4A081C1: strncpy (mc_replace_strmem.c:329) ==3682== by 0x4022F1: parseCommandLineInputs (starch.c:589) ==3682== by 0x402F20: main (starch.c:46) ==3682== Address 0x7fedffe11 is on thread 1 stac
Here are two relevant lines; valgrind says the second line is incorrect:
uniqTag = (char *)malloc(strlen(argv[2]) + 1); strncpy(uniqTag, argv[2], strlen(argv[2]) + 1);
Since strlen(argv[2]) + 1 > strlen(argv[2]) , this should lead to termination with zero uniqTag .