diff options
-rw-r--r-- | configure.in | 7 | ||||
-rw-r--r-- | include/my_sys.h | 4 | ||||
-rw-r--r-- | mysql-test/valgrind.supp | 14 | ||||
-rw-r--r-- | mysys/my_compress.c | 74 | ||||
-rw-r--r-- | sql/handler.cc | 3 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 6 | ||||
-rw-r--r-- | storage/archive/azio.c | 40 |
7 files changed, 100 insertions, 48 deletions
diff --git a/configure.in b/configure.in index 1ab9f1a3f36..a46d25b1d12 100644 --- a/configure.in +++ b/configure.in @@ -9,8 +9,11 @@ AC_CANONICAL_SYSTEM # remember to also update version.c in ndb # # When changing major version number please also check switch statement -# in mysqlbinlog::check_master_version(). -AM_INIT_AUTOMAKE(mysql, 5.1.35-maria-beta2) +# in mysqlbinlog.cc / check_master_version(). +# +# When merging new MySQL releases, update the version number to match the +# MySQL version number, but reset the maria subrelease (-beta1). +AM_INIT_AUTOMAKE(mysql, 5.1.35-maria-beta1) AM_CONFIG_HEADER([include/config.h:config.h.in]) PROTOCOL_VERSION=10 diff --git a/include/my_sys.h b/include/my_sys.h index 4aa43165d05..fd1c486cead 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -879,6 +879,10 @@ extern my_bool my_compress(uchar *, size_t *, size_t *); extern my_bool my_uncompress(uchar *, size_t , size_t *); extern uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen); +extern void *my_az_allocator(void *dummy, unsigned int items, unsigned int size); +extern void my_az_free(void *dummy, void *address); +extern int my_compress_buffer(uchar *dest, size_t *destLen, + const uchar *source, size_t sourceLen); extern int packfrm(uchar *, size_t, uchar **, size_t *); extern int unpackfrm(uchar **, size_t *, const uchar *); diff --git a/mysql-test/valgrind.supp b/mysql-test/valgrind.supp index f30f5d2e3c5..2d90213b112 100644 --- a/mysql-test/valgrind.supp +++ b/mysql-test/valgrind.supp @@ -401,6 +401,20 @@ } { + dlclose memory loss from plugin variant 3 + Memcheck:Leak + fun:malloc + fun:_dl_scope_free + fun:_dl_close_worker + fun:_dl_close + fun:_dl_catch_error + fun:_dlerror_run + fun:dlclose + fun:_Z15free_plugin_memP12st_plugin_dl + fun:_Z13plugin_dl_delPK19st_mysql_lex_string +} + +{ dlopen / ptread_cancel_init memory loss on Suse Linux 10.3 32/64 bit Memcheck:Leak fun:*alloc diff --git a/mysys/my_compress.c b/mysys/my_compress.c index 45c4ab983cc..26626d70079 100644 --- a/mysys/my_compress.c +++ b/mysys/my_compress.c @@ -57,19 +57,85 @@ my_bool my_compress(uchar *packet, size_t *len, size_t *complen) } +/* + 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. +*/ +void *my_az_allocator(void *dummy, unsigned int items, unsigned int size) +{ + return my_malloc((size_t)items*(size_t)size, IF_VALGRIND(MY_ZEROFILL, MYF(0))); +} + +void my_az_free(void *dummy, void *address) +{ + my_free(address, MYF(MY_ALLOW_ZERO_PTR)); +} + +/* + This works like zlib compress(), but using custom memory allocators to work + better with my_malloc leak detection and Valgrind. +*/ +int my_compress_buffer(uchar *dest, size_t *destLen, + const uchar *source, size_t sourceLen) +{ + z_stream stream; + int err; + + stream.next_in = (Bytef*)source; + stream.avail_in = (uInt)sourceLen; + stream.next_out = (Bytef*)dest; + stream.avail_out = (uInt)*destLen; + if ((size_t)stream.avail_out != *destLen) + return Z_BUF_ERROR; + + stream.zalloc = (alloc_func)my_az_allocator; + stream.zfree = (free_func)my_az_free; + stream.opaque = (voidpf)0; + + err = deflateInit(&stream, Z_DEFAULT_COMPRESSION); + if (err != Z_OK) return err; + + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; + + err = deflateEnd(&stream); + return err; +} + uchar *my_compress_alloc(const uchar *packet, size_t *len, size_t *complen) { uchar *compbuf; - uLongf tmp_complen; int res; *complen= *len * 120 / 100 + 12; if (!(compbuf= (uchar *) my_malloc(*complen, MYF(MY_WME)))) return 0; /* Not enough memory */ - tmp_complen= (uLongf) *complen; - res= compress((Bytef*) compbuf, &tmp_complen, (Bytef*) packet, (uLong) *len); - *complen= tmp_complen; + res= my_compress_buffer(compbuf, complen, packet, *len); if (res != Z_OK) { diff --git a/sql/handler.cc b/sql/handler.cc index 44efa1cbe68..f18ef8d95fe 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -432,9 +432,6 @@ int ha_initialize_handlerton(st_plugin_int *plugin) { sql_print_error("Plugin '%s' init function returned error.", plugin->name.str); - /* Free data, so that we don't refer to it in ha_finalize_handlerton */ - my_free(hton, MYF(0)); - plugin->data= 0; goto err; } diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 59f9dccfc79..77991c4fe6f 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3243,7 +3243,7 @@ longlong Item_func_crc32::val_int() String *Item_func_compress::val_str(String *str) { int err= Z_OK, code; - ulong new_size; + size_t new_size; String *res; Byte *body; char *tmp, *last_char; @@ -3279,8 +3279,8 @@ String *Item_func_compress::val_str(String *str) body= ((Byte*)buffer.ptr()) + 4; // As far as we have checked res->is_empty() we can use ptr() - if ((err= compress(body, &new_size, - (const Bytef*)res->ptr(), res->length())) != Z_OK) + if ((err= my_compress_buffer(body, &new_size, (const uchar *)res->ptr(), + res->length())) != Z_OK) { code= err==Z_MEM_ERROR ? ER_ZLIB_Z_MEM_ERROR : ER_ZLIB_Z_BUF_ERROR; push_warning(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR,code,ER(code)); diff --git a/storage/archive/azio.c b/storage/archive/azio.c index 6030029ca9a..b6d66fc0739 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -16,6 +16,8 @@ #include <stdio.h> #include <string.h> +#include "my_sys.h" + static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */ static int const az_magic[3] = {0xfe, 0x03, 0x01}; /* az magic header */ @@ -37,40 +39,6 @@ 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, IF_VALGRIND(MY_ZEROFILL, MYF(0))); -} - -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 @@ -86,8 +54,8 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) int level = Z_DEFAULT_COMPRESSION; /* compression level */ int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */ - s->stream.zalloc = az_allocator; - s->stream.zfree = az_free; + s->stream.zalloc = my_az_allocator; + s->stream.zfree = my_az_free; s->stream.opaque = (voidpf)0; memset(s->inbuf, 0, AZ_BUFSIZE_READ); memset(s->outbuf, 0, AZ_BUFSIZE_WRITE); |