#At lp:maria 2704 knielsen@knielsen-hq.org 2009-05-22 After-merge fixes for problems seen in buildbot after merging MySQL-5.1.35. - Version number. - Valgrind false alarms in libz. - New variant of suppression for Valgrind warning in dlclose(). - Fix double free() in plugin init error case. modified: configure.in include/my_sys.h mysql-test/valgrind.supp mysys/my_compress.c sql/handler.cc sql/item_strfunc.cc storage/archive/azio.c per-file messages: configure.in Fix version number. We should reset the maria variant back to `1' when the MySQL version number increases. include/my_sys.h Fix false alarms in Valgrind for zlib. Apply same fix as for archive storage handler also to the cases of compression in the client protocol, and to the compression SQL function. mysql-test/valgrind.supp A new variant of the dlclose() suppression is needed now. mysys/my_compress.c Fix false alarms in Valgrind for zlib. Apply same fix as for archive storage handler also to the cases of compression in the client protocol, and to the compression SQL function. sql/handler.cc Fix a double free() in error case for plugin initialisation. sql/item_strfunc.cc Fix false alarms in Valgrind for zlib. Apply same fix as for archive storage handler also to the cases of compression in the client protocol, and to the compression SQL function. === modified file 'configure.in' --- a/configure.in 2009-04-25 10:05:32 +0000 +++ b/configure.in 2009-05-22 12:38:50 +0000 @@ -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 === modified file 'include/my_sys.h' --- a/include/my_sys.h 2009-04-25 10:05:32 +0000 +++ b/include/my_sys.h 2009-05-22 12:38:50 +0000 @@ -879,6 +879,10 @@ extern my_bool my_compress(uchar *, size 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 *); === modified file 'mysql-test/valgrind.supp' --- a/mysql-test/valgrind.supp 2009-04-08 16:55:26 +0000 +++ b/mysql-test/valgrind.supp 2009-05-22 12:38:50 +0000 @@ -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 === modified file 'mysys/my_compress.c' --- a/mysys/my_compress.c 2009-04-25 10:05:32 +0000 +++ b/mysys/my_compress.c 2009-05-22 12:38:50 +0000 @@ -57,19 +57,85 @@ my_bool my_compress(uchar *packet, size_ } +/* + 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) { === modified file 'sql/handler.cc' --- a/sql/handler.cc 2009-04-25 10:05:32 +0000 +++ b/sql/handler.cc 2009-05-22 12:38:50 +0000 @@ -432,9 +432,6 @@ int ha_initialize_handlerton(st_plugin_i { 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; } === modified file 'sql/item_strfunc.cc' --- a/sql/item_strfunc.cc 2009-04-25 10:05:32 +0000 +++ b/sql/item_strfunc.cc 2009-05-22 12:38:50 +0000 @@ -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(Stri 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)); === modified file 'storage/archive/azio.c' --- a/storage/archive/azio.c 2009-05-19 09:28:05 +0000 +++ b/storage/archive/azio.c 2009-05-22 12:38:50 +0000 @@ -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 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);