From: Jon Olav Hauglid Date: September 16 2010 2:16pm Subject: bzr commit into mysql-5.5-runtime branch (jon.hauglid:3140) List-Archive: http://lists.mysql.com/commits/118414 Message-Id: <201009161418.o8GDiV5L007870@acsinet15.oracle.com> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="===============8848440188325416484==" --===============8848440188325416484== MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline #At file:///export/home/x/mysql-5.5-runtime-test/ based on revid:dlenev@stripped 3140 Jon Olav Hauglid 2010-09-16 [merge] Merge from mysql-5.5-bugfixing to mysql-5.5-runtime. added: mysql-test/suite/perfschema/r/checksum.result mysql-test/suite/perfschema/t/checksum.test modified: dbug/dbug.c include/mysql/service_my_snprintf.h mysql-test/suite/perfschema/include/upgrade_check.inc mysql-test/valgrind.supp sql/mysqld.cc storage/perfschema/ha_perfschema.cc storage/perfschema/table_events_waits.cc storage/perfschema/table_events_waits.h strings/my_vsnprintf.c unittest/mysys/my_vsnprintf-t.c === modified file 'dbug/dbug.c' --- a/dbug/dbug.c 2010-07-15 11:16:06 +0000 +++ b/dbug/dbug.c 2010-09-15 11:33:22 +0000 @@ -1335,15 +1335,11 @@ void _db_doprnt_(const char *format,...) * This function is intended as a * vfprintf clone with consistent, platform independent output for * problematic formats like %p, %zd and %lld. - * However: full functionality for my_vsnprintf has not been backported yet, - * so code using "%g" or "%f" will have undefined behaviour. */ static void DbugVfprintf(FILE *stream, const char* format, va_list args) { char cvtbuf[1024]; - size_t len; - /* Do not use my_vsnprintf, it does not support "%g". */ - len = vsnprintf(cvtbuf, sizeof(cvtbuf), format, args); + (void) my_vsnprintf(cvtbuf, sizeof(cvtbuf), format, args); (void) fprintf(stream, "%s\n", cvtbuf); } === modified file 'include/mysql/service_my_snprintf.h' --- a/include/mysql/service_my_snprintf.h 2010-07-20 19:34:20 +0000 +++ b/include/mysql/service_my_snprintf.h 2010-09-15 11:33:22 +0000 @@ -53,7 +53,7 @@ can be 'l', 'll', or 'z'. Supported formats are 's' (null pointer is accepted, printed as - "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', 'o', + "(null)"), 'b' (extension, see below), 'c', 'd', 'i', 'u', 'x', 'o', 'X', 'p' (works as 0x%x). Standard syntax for positional arguments $n is supported. === modified file 'mysql-test/suite/perfschema/include/upgrade_check.inc' --- a/mysql-test/suite/perfschema/include/upgrade_check.inc 2010-07-20 19:15:29 +0000 +++ b/mysql-test/suite/perfschema/include/upgrade_check.inc 2010-09-13 23:19:39 +0000 @@ -18,7 +18,7 @@ # --error 1 ---exec $MYSQL_UPGRADE --skip-verbose > $out_file 2> $err_file +--exec $MYSQL_UPGRADE --skip-verbose --force > $out_file 2> $err_file # Verify that mysql_upgrade complained about the performance_schema --cat_file $err_file === added file 'mysql-test/suite/perfschema/r/checksum.result' --- a/mysql-test/suite/perfschema/r/checksum.result 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/perfschema/r/checksum.result 2010-09-15 18:20:48 +0000 @@ -0,0 +1,34 @@ +checksum table performance_schema.COND_INSTANCES; +checksum table performance_schema.EVENTS_WAITS_CURRENT; +checksum table performance_schema.EVENTS_WAITS_HISTORY; +checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; +checksum table performance_schema.FILE_INSTANCES; +checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME; +checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE; +checksum table performance_schema.MUTEX_INSTANCES; +checksum table performance_schema.PERFORMANCE_TIMERS; +checksum table performance_schema.RWLOCK_INSTANCES; +checksum table performance_schema.SETUP_CONSUMERS; +checksum table performance_schema.SETUP_INSTRUMENTS; +checksum table performance_schema.SETUP_TIMERS; +checksum table performance_schema.THREADS; +checksum table performance_schema.COND_INSTANCES extended; +checksum table performance_schema.EVENTS_WAITS_CURRENT extended; +checksum table performance_schema.EVENTS_WAITS_HISTORY extended; +checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG extended; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE extended; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME extended; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME extended; +checksum table performance_schema.FILE_INSTANCES extended; +checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME extended; +checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE extended; +checksum table performance_schema.MUTEX_INSTANCES extended; +checksum table performance_schema.PERFORMANCE_TIMERS extended; +checksum table performance_schema.RWLOCK_INSTANCES extended; +checksum table performance_schema.SETUP_CONSUMERS extended; +checksum table performance_schema.SETUP_INSTRUMENTS extended; +checksum table performance_schema.SETUP_TIMERS extended; +checksum table performance_schema.THREADS extended; === added file 'mysql-test/suite/perfschema/t/checksum.test' --- a/mysql-test/suite/perfschema/t/checksum.test 1970-01-01 00:00:00 +0000 +++ b/mysql-test/suite/perfschema/t/checksum.test 2010-09-15 18:20:48 +0000 @@ -0,0 +1,64 @@ +# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ + +# Tests for PERFORMANCE_SCHEMA + +--source include/not_embedded.inc +--source include/have_perfschema.inc + +# +# The checksum value itself is random (data is volatile), +# just testing that this does not crash +# +--disable_result_log + +checksum table performance_schema.COND_INSTANCES; +checksum table performance_schema.EVENTS_WAITS_CURRENT; +checksum table performance_schema.EVENTS_WAITS_HISTORY; +checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME; +checksum table performance_schema.FILE_INSTANCES; +checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME; +checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE; +checksum table performance_schema.MUTEX_INSTANCES; +checksum table performance_schema.PERFORMANCE_TIMERS; +checksum table performance_schema.RWLOCK_INSTANCES; +checksum table performance_schema.SETUP_CONSUMERS; +checksum table performance_schema.SETUP_INSTRUMENTS; +checksum table performance_schema.SETUP_TIMERS; +checksum table performance_schema.THREADS; + +checksum table performance_schema.COND_INSTANCES extended; +checksum table performance_schema.EVENTS_WAITS_CURRENT extended; +checksum table performance_schema.EVENTS_WAITS_HISTORY extended; +checksum table performance_schema.EVENTS_WAITS_HISTORY_LONG extended; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_INSTANCE extended; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_BY_THREAD_BY_EVENT_NAME extended; +checksum table performance_schema.EVENTS_WAITS_SUMMARY_GLOBAL_BY_EVENT_NAME extended; +checksum table performance_schema.FILE_INSTANCES extended; +checksum table performance_schema.FILE_SUMMARY_BY_EVENT_NAME extended; +checksum table performance_schema.FILE_SUMMARY_BY_INSTANCE extended; +checksum table performance_schema.MUTEX_INSTANCES extended; +checksum table performance_schema.PERFORMANCE_TIMERS extended; +checksum table performance_schema.RWLOCK_INSTANCES extended; +checksum table performance_schema.SETUP_CONSUMERS extended; +checksum table performance_schema.SETUP_INSTRUMENTS extended; +checksum table performance_schema.SETUP_TIMERS extended; +checksum table performance_schema.THREADS extended; + +--enable_result_log + === modified file 'mysql-test/valgrind.supp' --- a/mysql-test/valgrind.supp 2010-06-07 08:47:04 +0000 +++ b/mysql-test/valgrind.supp 2010-09-09 21:33:35 +0000 @@ -745,3 +745,28 @@ Memcheck:Addr1 fun:buf_buddy_relocate } + +# +# See related Bug#56666 +# Race condition between the server main thread and the kill server thread. +# +# Because of this race condition, the call to shutdown_performance_schema() +# was commented in sql/mysqld.cc, causing the reported leaks. +# + +{ + missing shutdown_performance_schema 1 + Memcheck:Leak + fun:malloc + fun:_Z10pfs_mallocmi +} + +{ + missing shutdown_performance_schema 2 + Memcheck:Leak + fun:malloc + fun:my_malloc + fun:_lf_alloc_new + fun:lf_hash_insert +} + === modified file 'sql/mysqld.cc' --- a/sql/mysqld.cc 2010-09-02 18:37:04 +0000 +++ b/sql/mysqld.cc 2010-09-14 21:40:50 +0000 @@ -1395,6 +1395,12 @@ static void mysqld_exit(int exit_code) mysql_audit_finalize(); clean_up_mutexes(); clean_up_error_log_mutex(); +#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE + /* + Bug#56666 needs to be fixed before calling: + shutdown_performance_schema(); + */ +#endif my_end(opt_endinfo ? MY_CHECK_ERROR | MY_GIVE_INFO : 0); exit(exit_code); /* purecov: inspected */ } @@ -2733,6 +2739,11 @@ pthread_handler_t signal_hand(void *arg if (!abort_loop) { abort_loop=1; // mark abort for threads +#ifdef HAVE_PSI_INTERFACE + /* Delete the instrumentation for the signal thread */ + if (likely(PSI_server != NULL)) + PSI_server->delete_current_thread(); +#endif #ifdef USE_ONE_SIGNAL_HAND pthread_t tmp; if (mysql_thread_create(0, /* Not instrumented */ @@ -4588,6 +4599,15 @@ int mysqld_main(int argc, char **argv) #endif #endif /* __WIN__ */ +#ifdef HAVE_PSI_INTERFACE + /* + Disable the main thread instrumentation, + to avoid recording events during the shutdown. + */ + if (PSI_server) + PSI_server->delete_current_thread(); +#endif + /* Wait until cleanup is done */ mysql_mutex_lock(&LOCK_thread_count); while (!ready_to_exit) @@ -4605,18 +4625,6 @@ int mysqld_main(int argc, char **argv) } #endif clean_up(1); -#ifdef HAVE_PSI_INTERFACE - /* - Disable the instrumentation, to avoid recording events - during the shutdown. - */ - if (PSI_server) - { - PSI_server->delete_current_thread(); - PSI_server= NULL; - } - shutdown_performance_schema(); -#endif mysqld_exit(0); } === modified file 'storage/perfschema/ha_perfschema.cc' --- a/storage/perfschema/ha_perfschema.cc 2010-07-15 23:44:45 +0000 +++ b/storage/perfschema/ha_perfschema.cc 2010-09-10 09:10:38 +0000 @@ -20,6 +20,7 @@ #include "my_global.h" #include "my_pthread.h" +#include "my_atomic.h" #include "sql_plugin.h" #include "mysql/plugin.h" #include "ha_perfschema.h" @@ -28,6 +29,17 @@ #include "pfs_instr_class.h" #include "pfs_instr.h" +#ifdef MY_ATOMIC_MODE_DUMMY +/* + The performance schema can can not function with MY_ATOMIC_MODE_DUMMY, + a fully functional implementation of MY_ATOMIC should be used instead. + If the build fails with this error message: + - either use a different ./configure --with-atomic-ops option + - or do not build with the performance schema. +*/ +#error "The performance schema needs a functional MY_ATOMIC implementation." +#endif + handlerton *pfs_hton= NULL; static handler* pfs_create_handler(handlerton *hton, === modified file 'storage/perfschema/table_events_waits.cc' --- a/storage/perfschema/table_events_waits.cc 2010-08-12 09:51:58 +0000 +++ b/storage/perfschema/table_events_waits.cc 2010-09-15 18:20:48 +0000 @@ -187,7 +187,7 @@ void table_events_waits_common::clear_ob */ void table_events_waits_common::make_row(bool thread_own_wait, PFS_thread *pfs_thread, - PFS_events_waits *wait) + volatile PFS_events_waits *wait) { pfs_lock lock; PFS_thread *safe_thread; @@ -251,21 +251,27 @@ void table_events_waits_common::make_row case WAIT_CLASS_TABLE: m_row.m_object_type= "TABLE"; m_row.m_object_type_length= 5; - memcpy(m_row.m_object_schema, wait->m_schema_name, - wait->m_schema_name_length); m_row.m_object_schema_length= wait->m_schema_name_length; - memcpy(m_row.m_object_name, wait->m_object_name, - wait->m_object_name_length); + if (unlikely((m_row.m_object_schema_length == 0) || + (m_row.m_object_schema_length > sizeof(m_row.m_object_schema)))) + return; + memcpy(m_row.m_object_schema, wait->m_schema_name, m_row.m_object_schema_length); m_row.m_object_name_length= wait->m_object_name_length; + if (unlikely((m_row.m_object_name_length == 0) || + (m_row.m_object_name_length > sizeof(m_row.m_object_name)))) + return; + memcpy(m_row.m_object_name, wait->m_object_name, m_row.m_object_name_length); safe_class= &global_table_class; break; case WAIT_CLASS_FILE: m_row.m_object_type= "FILE"; m_row.m_object_type_length= 4; m_row.m_object_schema_length= 0; - memcpy(m_row.m_object_name, wait->m_object_name, - wait->m_object_name_length); m_row.m_object_name_length= wait->m_object_name_length; + if (unlikely((m_row.m_object_name_length == 0) || + (m_row.m_object_name_length > sizeof(m_row.m_object_name)))) + return; + memcpy(m_row.m_object_name, wait->m_object_name, m_row.m_object_name_length); safe_class= sanitize_file_class((PFS_file_class*) wait->m_class); break; case NO_WAIT_CLASS: === modified file 'storage/perfschema/table_events_waits.h' --- a/storage/perfschema/table_events_waits.h 2010-07-16 00:06:33 +0000 +++ b/storage/perfschema/table_events_waits.h 2010-09-15 18:20:48 +0000 @@ -137,7 +137,7 @@ protected: void clear_object_columns(); void make_row(bool thread_own_wait, PFS_thread *pfs_thread, - PFS_events_waits *wait); + volatile PFS_events_waits *wait); /** Current row. */ row_events_waits m_row; === modified file 'strings/my_vsnprintf.c' --- a/strings/my_vsnprintf.c 2009-12-28 12:54:16 +0000 +++ b/strings/my_vsnprintf.c 2010-09-15 11:33:22 +0000 @@ -255,7 +255,7 @@ static char *process_int_arg(char *to, c if ((to_length= (size_t) (end-to)) < 16 || length) store_start= buff; - if (arg_type == 'd') + if (arg_type == 'd' || arg_type == 'i') store_end= longlong10_to_str(par, store_start, -10); else if (arg_type == 'u') store_end= longlong10_to_str(par, store_start, 10); @@ -399,6 +399,7 @@ start: args_arr[i].double_arg= va_arg(ap, double); break; case 'd': + case 'i': case 'u': case 'x': case 'X': @@ -406,7 +407,7 @@ start: case 'p': if (args_arr[i].have_longlong) args_arr[i].longlong_arg= va_arg(ap,longlong); - else if (args_arr[i].arg_type == 'd') + else if (args_arr[i].arg_type == 'd' || args_arr[i].arg_type == 'i') args_arr[i].longlong_arg= va_arg(ap, int); else args_arr[i].longlong_arg= va_arg(ap, uint); @@ -458,6 +459,7 @@ start: break; } case 'd': + case 'i': case 'u': case 'x': case 'X': @@ -472,7 +474,7 @@ start: if (args_arr[print_arr[i].arg_idx].have_longlong) larg = args_arr[print_arr[i].arg_idx].longlong_arg; - else if (print_arr[i].arg_type == 'd') + else if (print_arr[i].arg_type == 'd' || print_arr[i].arg_type == 'i' ) larg = (int) args_arr[print_arr[i].arg_idx].longlong_arg; else larg= (uint) args_arr[print_arr[i].arg_idx].longlong_arg; @@ -615,8 +617,8 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, to= process_dbl_arg(to, end, width, d, *fmt); continue; } - else if (*fmt == 'd' || *fmt == 'u' || *fmt == 'x' || *fmt == 'X' || - *fmt == 'p' || *fmt == 'o') + else if (*fmt == 'd' || *fmt == 'i' || *fmt == 'u' || *fmt == 'x' || + *fmt == 'X' || *fmt == 'p' || *fmt == 'o') { /* Integer parameter */ longlong larg; @@ -625,7 +627,7 @@ size_t my_vsnprintf_ex(CHARSET_INFO *cs, if (have_longlong) larg = va_arg(ap,longlong); - else if (*fmt == 'd') + else if (*fmt == 'd' || *fmt == 'i') larg = va_arg(ap, int); else larg= va_arg(ap, uint); === modified file 'unittest/mysys/my_vsnprintf-t.c' --- a/unittest/mysys/my_vsnprintf-t.c 2009-12-28 12:54:16 +0000 +++ b/unittest/mysys/my_vsnprintf-t.c 2010-09-15 11:33:22 +0000 @@ -31,7 +31,7 @@ void test1(const char *res, const char * int main(void) { - plan(54); + plan(58); test1("Constant string", "Constant string"); @@ -44,6 +44,8 @@ int main(void) "Format specifier c %c", '!'); test1("Format specifier d 1", "Format specifier d %d", 1); + test1("Format specifier i 1", + "Format specifier i %i", 1); test1("Format specifier u 2", "Format specifier u %u", 2); test1("Format specifier o 375", @@ -77,6 +79,9 @@ int main(void) test1("Length modifiers work: 1 * -1 * 2 * 3", "Length modifiers work: %d * %ld * %lld * %zd", 1, -1L, 2LL, (size_t)3); + test1("Length modifiers work: 1 * -1 * 2 * 3", + "Length modifiers work: %i * %li * %lli * %zd", 1, -1L, 2LL, (size_t)3); + test1("long long X: 123456789abcdef0", "long long X: %llx", 0x123456789abcdef0LL); @@ -121,6 +126,10 @@ int main(void) "Hello int, %d", 1); test1("Hello int, -1", "Hello int, %d", -1); + test1("Hello int, 1", + "Hello int, %i", 1); + test1("Hello int, -1", + "Hello int, %i", -1); test1("Hello string 'I am a string'", "Hello string '%s'", "I am a string"); test1("Hello hack hack hack hack hack hack hack 1", --===============8848440188325416484== MIME-Version: 1.0 Content-Type: text/bzr-bundle; charset="us-ascii"; name="bzr/jon.hauglid@stripped" Content-Transfer-Encoding: 7bit Content-Disposition: inline # Bazaar merge directive format 2 (Bazaar 0.90) # revision_id: jon.hauglid@stripped # target_branch: file:///export/home/x/mysql-5.5-runtime-test/ # testament_sha1: ec338a44b55c5ed9fb813b350944fe1810758274 # timestamp: 2010-09-16 16:16:40 +0200 # source_branch: file:///export/home/x/mysql-5.5-bugfixing/ # base_revision_id: dlenev@stripped # # Begin bundle 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 QQf+hEA= --===============8848440188325416484==--