Do I need to worry about Valgrind message errors outside of my application?

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]; /* initialize deflate state */ strm.zalloc = Z_NULL; strm.zfree = Z_NULL; strm.opaque = Z_NULL; /* deflateInit2 allows creation of archive with gzip header, ie a gzip file */ /* cf. http://www.zlib.net/manual.html */ ret = deflateInit2(&strm, level, Z_DEFLATED, (15+16), 8, Z_DEFAULT_STRATEGY); if (ret != Z_OK) return ret; /* compress until end of file */ 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; /* invalid read happens here */ 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); /* clean up and return */ (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 .

+4
source share
2 answers

In this case, I would say that you do it. The arguments to the libc function come from your program. I would venture to suggest and say that you have one error in the code, which leads to the fact that fwrite reads one byte from the end of the source buffer.

EDIT:

By the way, such a small error can often remain invisible (i.e. your code does not crash), because both the compiler and the memory allocator usually allocate memory blocks in certain sizes and align them at the edges of words. This means that many times there is a small area behind the requested end of the buffer, which you can access without calling the memory protection code. Of course, your code may just break if you change the compiler, libc, platform or bit (for example, go from 64 to 32 bits).

Valgrind has error suppression lists in libc, which you can usually find in / usr / lib 64 / valgrind / default.supp or / usr / lib / valgrind / default.supp. There are quite a few problems that valgrind detects in libc, many of which intentionally seek to optimize the code, but due to limitations in 99% of cases, this is the verified code that causes the problem.

EDIT2:

Keep in mind that, like most debugging tools, Valgrind will provide infinitely more useful information about the problems that it detects if you compile your code using debugging symbols. He will be able to tell you specific lines of code that are related to the problem, even if they are often not where the problem is relevant. If you use GCC, just add -g to your options to compile the code using debugging symbols. In the product release, please remember to remove this flag!

+5
source

You must keep an eye on the call stack until you get the code that belongs to you and look at the origin of the error. In this case, STARCH_gzip_deflate apparently causes fwrite do something bad (maybe bad FILE * or the buffer you are trying to write), which is why valgrind barks at you.

Perhaps this is not really a mistake, or that it is not your mistake. But it probably is.

+1
source

All Articles