|
From: Tilman S. <ti...@co...> - 2005-05-26 13:07:38
|
Hi,
I suggest to add the following two suppressions to the default set:
{
bogus warning in zlib
Memcheck:Cond
obj:/usr/lib/libz.so.1.2.2
obj:/usr/lib/libz.so.1.2.2
fun:deflate
fun:compress2
}
{
bogus warning in zlib
Memcheck:Cond
obj:/usr/lib/libz.so.1.2.2
obj:/usr/lib/libz.so.1.2.2
fun:deflate
fun:compress2
}
According to Mark Adler, that bug is safe and it probably won't be
fixed:
http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=270070
Regards,
Tilman
--
learn to quote: http://www.netmeister.org/news/learn2quote.html
|
|
From: Julian S. <js...@ac...> - 2005-05-30 07:26:34
|
Hi. This is an interesting one. First off, I can reproduce this using zlib-1.2.2 and the test program posted at http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=270070, using current Valgrind 3 sources, on x86. I'm reluctant to add these suppressions without understanding what's going in on detail. A lot of thought and effort went into making Valgrind (Memcheck) have a low false-positive rate, and if this shows up a flaw in Memcheck's instrumentation scheme I want to know what it is. In http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=270070 Mark writes: > I went through that in detail about a year or two ago and concluded > that it was not a problem, and furthermore could not even cause > indeterminism in the result of deflating. It was intentional in the > design to improve speed. Mark, could you explain how the use of uninitialised values from memory is made safe here? I'm looking at this do { } while (*++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && *++scan == *++match && scan < strend); and it's not clear how scan can be moved forward some indeterminate amount based on garbage in memory and yet the deflate result is well-defined. As background: Memcheck does occasionally generate false errors. These have been looked into quite extensively, and as far as I know always revolve around getting the x86 %eflags register into a partially defined state at high levels of optimisation. This one seems different -- removing -O3/2/1 from the compile flags does not make the report go away. An ideal outcome is that Mark explains how this behaviour is safe in zlib. I can then look at Memcheck's instrumentation phase to determine if/how it is possible to avoid these reports. J On Thursday 26 May 2005 14:07, Tilman Sauerbeck wrote: > Hi, > I suggest to add the following two suppressions to the default set: > > { > bogus warning in zlib > Memcheck:Cond > obj:/usr/lib/libz.so.1.2.2 > obj:/usr/lib/libz.so.1.2.2 > fun:deflate > fun:compress2 > } > { > bogus warning in zlib > Memcheck:Cond > obj:/usr/lib/libz.so.1.2.2 > obj:/usr/lib/libz.so.1.2.2 > fun:deflate > fun:compress2 > } > > According to Mark Adler, that bug is safe and it probably won't be > fixed: > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=270070 > > Regards, > Tilman |
|
From: Mark A. <ma...@al...> - 2005-05-30 19:23:46
|
On May 30, 2005, at 12:26 AM, Julian Seward wrote:
> Mark, could you explain how the use of uninitialised values from memory
> is made safe here? I'm looking at this
>
> do {
> } while (*++scan == *++match && *++scan == *++match &&
> *++scan == *++match && *++scan == *++match &&
> *++scan == *++match && *++scan == *++match &&
> *++scan == *++match && *++scan == *++match &&
> scan < strend);
>
> and it's not clear how scan can be moved forward some indeterminate
> amount based on garbage in memory and yet the deflate result is
> well-defined.
The output of the loop is where the first mismatch is (scan). If
uninitialized data is accessed in the process, then all of the
initialized data matched, and maybe some of the uninitialized data as
well. Later the length of the match is truncated to the length of the
initialized data, so it doesn't matter how far into the uninitialized
data the loop progressed.
This line limits nice_match to be no longer than the uninitialized data:
if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
This line exits the longest match search loop if a match that long is
found (or longer if some uninitialized data matched):
if (len >= nice_match) break;
And these lines return a match length limited to the length of the
initialized data:
if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
return s->lookahead;
> An ideal outcome is that Mark explains how this behaviour
> is safe in zlib. I can then look at Memcheck's instrumentation
> phase to determine if/how it is possible to avoid these
> reports.
valgrind would have to be pretty smart to figure out what s->lookahead
means, trace the values of nice_match, len, and best_len, and figure
out from all that that the uninitialized data didn't affect the return
value. The only semi-reasonable automatic process I could imagine
would be for valgrind to set the first unintialized byte to all 256
values, run the code each time, and see that the returned value is not
affected (as well as all the side effects of the routine on the state
structure). Then if another uninitialized byte is accessed, which it
will be for one of the previous uninitialized byte values, do that all
over again, and so on. Good luck.
mark
|