From: Tor Didriksen Date: September 26 2012 2:09pm Subject: bzr push into mysql-5.6 branch (tor.didriksen:4335 to 4336) Bug#14649493 List-Archive: http://lists.mysql.com/commits/144867 X-Bug: 14649493 Message-Id: <20120926140905.23919.967.4336@atum07.no.oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 4336 Tor Didriksen 2012-09-26 Bug#14649493 ASSERTION FAILURE IN __GCOV_FLUSH IN _DB_SUICIDE_ (DBUG_SUICIDE) Grab THR_LOCK_gcov before calling __gcov_flush() to avoid multiple parallel calls. @ mysys/stacktrace.c Remove the ifdef HAVE_gcov code (note the lowercase) We never define that macro anymore, and the flushing of gcov data is now done in _db_suicide_ anyways. modified: dbug/dbug.c include/my_dbug.h mysys/stacktrace.c unittest/gunit/dbug-t.cc 4335 Akhila Maddukuri 2012-09-26 [merge] Description: ----------- After compiling from source, during make test I got the following error: test main.loaddata failed with error CURRENT_TEST: main.loaddata mysqltest: At line 592: query 'LOAD DATA INFILE 'tmpp.txt' INTO TABLE t1 CHARACTER SET ucs2 (@b) SET a=REVERSE(@b)' failed: 1115: Unknown character set: 'ucs2' I noticed other tests are skipped because of no ucs2 main.mix2_myisam_ucs2 [ skipped ] Test requires:' have_ucs2' Should main.loaddata be skipped if there is no ucs2 How To Repeat: ------------- Run make test on compiled source that doesn't have ucs2 Suggested fix: ------------- the failing piece of the test should be moved from mysql-test/t/loaddata.test to mysql-test/t/ctype_ucs.test. modified: mysql-test/r/ctype_ucs.result mysql-test/r/loaddata.result mysql-test/t/ctype_ucs.test mysql-test/t/loaddata.test === modified file 'dbug/dbug.c' --- a/dbug/dbug.c 2012-09-18 15:33:08 +0000 +++ b/dbug/dbug.c 2012-09-26 13:52:56 +0000 @@ -356,6 +356,14 @@ static void DbugVfprintf(FILE *stream, c #include static pthread_mutex_t THR_LOCK_dbug; + +/** + A mutex protecting flushing of gcov data, see _db_flush_gcov_(). + We don't re-use THR_LOCK_dbug, because that would disallow: + DBUG_LOCK_FILE; ..... DBUG_SUICIDE(); .... DBUG_UNLOCK_FILE; +*/ +static pthread_mutex_t THR_LOCK_gcov; + /** Lock, to protect @c init_settings. For performance reasons, @@ -378,6 +386,7 @@ static CODE_STATE *code_state(void) { init_done=TRUE; pthread_mutex_init(&THR_LOCK_dbug, NULL); + pthread_mutex_init(&THR_LOCK_gcov, NULL); my_rwlock_init(&THR_LOCK_init_settings, NULL); memset(&init_settings, 0, sizeof(init_settings)); init_settings.out_file=stderr; @@ -2383,6 +2392,16 @@ void _db_flush_() extern void __gcov_flush(); #endif +void _db_flush_gcov_() +{ +#ifdef HAVE_GCOV + // Gcov will assert() if we try to flush in parallel. + pthread_mutex_lock(&THR_LOCK_gcov); + __gcov_flush(); + pthread_mutex_unlock(&THR_LOCK_gcov); +#endif +} + void _db_suicide_() { int retval; @@ -2392,7 +2411,7 @@ void _db_suicide_() #ifdef HAVE_GCOV fprintf(stderr, "Flushing gcov data\n"); fflush(stderr); - __gcov_flush(); + _db_flush_gcov_(); #endif fprintf(stderr, "SIGKILL myself\n"); === modified file 'include/my_dbug.h' --- a/include/my_dbug.h 2011-09-20 09:20:12 +0000 +++ b/include/my_dbug.h 2012-09-26 13:52:56 +0000 @@ -133,6 +133,7 @@ extern const char* _db_get_func_(void); #define DBUG_SUICIDE() DBUG_ABORT() #else extern void _db_suicide_(); +extern void _db_flush_gcov_(); #define DBUG_SUICIDE() (_db_flush_(), _db_suicide_()) #endif === modified file 'mysys/stacktrace.c' --- a/mysys/stacktrace.c 2012-03-08 09:44:21 +0000 +++ b/mysys/stacktrace.c 2012-09-26 13:52:56 +0000 @@ -418,18 +418,7 @@ end: /* Produce a core for the thread */ void my_write_core(int sig) { -#ifdef HAVE_gcov - extern void __gcov_flush(void); -#endif signal(sig, SIG_DFL); -#ifdef HAVE_gcov - /* - For GCOV build, crashing will prevent the writing of code coverage - information from this process, causing gcov output to be incomplete. - So we force the writing of coverage information here before terminating. - */ - __gcov_flush(); -#endif pthread_kill(pthread_self(), sig); #if defined(P_MYID) && !defined(SCO) /* On Solaris, the above kill is not enough */ === modified file 'unittest/gunit/dbug-t.cc' --- a/unittest/gunit/dbug-t.cc 2011-12-20 09:51:05 +0000 +++ b/unittest/gunit/dbug-t.cc 2012-09-26 13:52:56 +0000 @@ -1,4 +1,4 @@ -/* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. +/* Copyright (c) 2010, 2012, 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 @@ -17,9 +17,16 @@ #include "my_config.h" #include +#include "thread_utils.h" + #include "my_global.h" #include "my_dbug.h" +using thread::Notification; +using thread::Thread; + +namespace { + #if defined(DBUG_OFF) TEST(DebugTest, NoSuicide) { @@ -32,3 +39,38 @@ TEST(DebugDeathTest, Suicide) EXPECT_DEATH_IF_SUPPORTED(DBUG_SUICIDE(), ""); } #endif + + +#if !defined(DBUG_OFF) && !defined(__WIN__) +class DbugGcovThread : public Thread +{ +public: + DbugGcovThread(Notification *start_notification) + : m_start_notification(start_notification) + {} + + virtual void run() + { + m_start_notification->notify(); + _db_flush_gcov_(); + } + +private: + Notification *m_start_notification; +}; + + +TEST(DebugFlushGcov, FlushGcovParallel) +{ + Notification start_notification; + DbugGcovThread debug_thread(&start_notification); + debug_thread.start(); + + // Wait for the other thread to start, then flush in parallel. + start_notification.wait_for_notification(); + _db_flush_gcov_(); + debug_thread.join(); +} +#endif + +} No bundle (reason: useless for push emails).