← Back to team overview

maria-developers team mailing list archive

[patch 07/11] Fix Valgrind false alarms on zlib operations in archive storage engine

 

The zlib code does operations on uninitialised parts of internal
memory, but subsequently does bounds checks and ignores the results of
any such undefined operations. This causes Valgrind to give false
alarms.

Fix by making memory allocated by zlib initialised #ifdef HAVE_purify.

Also make zlib use my_malloc() for better leak checking etc.

This is better than adding lots of suppressions for zlib operations:

 - No need to constantly add new suppressions for different versions of zlib.

 - Less risk of suppressing a real problem (like trying to
   compress/decompress uninitialised data).

=== modified file 'storage/archive/azio.c'
---
 storage/archive/azio.c |   44 ++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 42 insertions(+), 2 deletions(-)

Index: storage/archive/azio.c
===================================================================
--- storage/archive/azio.c.orig	2009-04-07 13:40:36.000000000 +0200
+++ storage/archive/azio.c	2009-04-07 13:42:16.000000000 +0200
@@ -37,6 +37,46 @@ void putLong(File file, uLong x);
 uLong  getLong(azio_stream *s);
 void read_header(azio_stream *s, unsigned char *buffer);
 
+/*
+  Valgrind normally gives false alarms for zlib operations, in the form of
+  "conditional jump depends on uninitialised values" etc. The reason is
+  explained in the zlib FAQ (http://www.zlib.net/zlib_faq.html#faq36):
+
+    "That is intentional for performance reasons, and the output of deflate
+    is not affected."
+
+  Also discussed on a blog
+  (http://www.sirena.org.uk/log/2006/02/19/zlib-generating-valgrind-warnings/):
+
+    "...loop unrolling in the zlib library causes the mentioned
+    “Conditional jump or move depends on uninitialised value(s)”
+    warnings. These are safe since the results of the comparison are
+    subsequently ignored..."
+
+    "the results of the calculations are discarded by bounds checking done
+    after the loop exits"
+
+  Fix by initializing the memory allocated by zlib when running under Valgrind.
+
+  This fix is safe, since such memory is only used internally by zlib, so we
+  will not hide any bugs in mysql this way.
+*/
+static void *az_allocator(void *dummy, uInt items, uInt size)
+{
+  return my_malloc((size_t)items * (size_t)size,
+#ifdef HAVE_purify
+                   MY_ZEROFILL
+#else
+                   MYF(0)
+#endif
+                   );
+}
+
+static void az_free(void *dummy, void *address)
+{
+  my_free(address, MYF(MY_ALLOW_ZERO_PTR));
+}
+
 /* ===========================================================================
   Opens a gzip (.gz) file for reading or writing. The mode parameter
   is as in fopen ("rb" or "wb"). The file is given either by file descriptor
@@ -52,8 +92,8 @@ int az_open (azio_stream *s, const char 
   int level = Z_DEFAULT_COMPRESSION; /* compression level */
   int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
 
-  s->stream.zalloc = (alloc_func)0;
-  s->stream.zfree = (free_func)0;
+  s->stream.zalloc = az_allocator;
+  s->stream.zfree = az_free;
   s->stream.opaque = (voidpf)0;
   memset(s->inbuf, 0, AZ_BUFSIZE_READ);
   memset(s->outbuf, 0, AZ_BUFSIZE_WRITE);

-- 



Follow ups

References