From: Jorgen Loland Date: September 29 2010 7:04am Subject: Re: bzr commit into mysql-next-mr-bugfixing branch (tor.didriksen:3300) Bug#52002 List-Archive: http://lists.mysql.com/commits/119332 Message-Id: <4CA2E4E4.8030505@oracle.com> MIME-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit Patch approved. On 09/28/2010 01:11 PM, Tor Didriksen wrote: > #At file:///export/home/didrik/repo/next-mr-bf-binlogcore/ based on revid:dao-gang.qu@stripped > > 3300 Tor Didriksen 2010-09-28 > Bug#52002 binlog_index may cause incorrect failure report on failing test that follows it > > For crash testing: kill the server without generating core file. > @ include/my_dbug.h > Use kill(getpid(), SIGKILL) which cannot be caught by signal handlers. > All DBUG_XXX macros should be no-ops in optimized mode, do that for DBUG_ABORT as well. > @ sql/binlog.cc > Kill server without generating core. > @ sql/handler.cc > Kill server without generating core. > @ unittest/gunit/CMakeLists.txt > Add unit test. > @ unittest/gunit/dbug-t.cc > Add unit test. > > added: > unittest/gunit/dbug-t.cc > modified: > include/my_dbug.h > sql/binlog.cc > sql/handler.cc > unittest/gunit/CMakeLists.txt > === modified file 'include/my_dbug.h' > --- a/include/my_dbug.h 2010-07-15 11:16:06 +0000 > +++ b/include/my_dbug.h 2010-09-28 11:11:50 +0000 > @@ -16,6 +16,14 @@ > #ifndef _dbug_h > #define _dbug_h > > +#ifdef HAVE_SYS_TYPES_H > +#include > +#endif > + > +#ifndef __WIN__ > +#include > +#endif > + > #ifdef __cplusplus > extern "C" { > #endif > @@ -111,6 +119,19 @@ extern const char* _db_get_func_(void); > #define DBUG_CRASH_VOID_RETURN \ > DBUG_CHECK_CRASH (_db_get_func_(), "_crash_return") > > +/* > + Make the program fail, without creating a core file. > + abort() will send SIGABRT which (most likely) generates core. > + Use SIGKILL instead, which cannot be caught. > + An alternative would be to use _exit(EXIT_FAILURE), > + but then valgrind would report lots of memory leaks. > + */ > +#ifdef __WIN__ > +#define DBUG_SUICIDE() DBUG_ABORT() > +#else > +#define DBUG_SUICIDE() (_db_flush_(), kill(getpid(), SIGKILL)) > +#endif > + > #else /* No debugger */ > > #define DBUG_ENTER(a1) > @@ -139,11 +160,14 @@ extern const char* _db_get_func_(void); > #define DBUG_EXPLAIN_INITIAL(buf,len) > #define DEBUGGER_OFF do { } while(0) > #define DEBUGGER_ON do { } while(0) > -#define DBUG_ABORT() abort() > +#define DBUG_ABORT() do { } while(0) > #define DBUG_CRASH_ENTER(func) > #define DBUG_CRASH_RETURN(val) do { return(val); } while(0) > #define DBUG_CRASH_VOID_RETURN do { return; } while(0) > > +/* NOOP in optimized mode. */ > +#define DBUG_SUICIDE() do { } while(0) > + > #endif > > #ifdef EXTRA_DEBUG > > === modified file 'sql/binlog.cc' > --- a/sql/binlog.cc 2010-09-17 13:22:22 +0000 > +++ b/sql/binlog.cc 2010-09-28 11:11:50 +0000 > @@ -1568,7 +1568,7 @@ bool MYSQL_BIN_LOG::open(const char *log > sql_print_error("MSYQL_BIN_LOG::open failed to sync the index file."); > DBUG_RETURN(1); > } > - DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_SUICIDE();); > #endif > > write_error= 0; > @@ -1668,7 +1668,7 @@ bool MYSQL_BIN_LOG::open(const char *log > if (write_file_name_to_index_file) > { > #ifdef HAVE_REPLICATION > - DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_SUICIDE();); > #endif > > DBUG_ASSERT(my_b_inited(&index_file) != 0); > @@ -1687,7 +1687,7 @@ bool MYSQL_BIN_LOG::open(const char *log > goto err; > > #ifdef HAVE_REPLICATION > - DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_SUICIDE();); > #endif > } > } > @@ -2139,7 +2139,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay > /* Store where we are in the new file for the execution thread */ > flush_relay_log_info(rli); > > - DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE();); > > mysql_mutex_lock(&rli->log_space_lock); > rli->relay_log.purge_logs(to_purge_if_included, included, > @@ -2267,7 +2267,7 @@ int MYSQL_BIN_LOG::purge_logs(const char > break; > } > > - DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_SUICIDE();); > > if ((error= sync_purge_index_file())) > { > @@ -2282,7 +2282,7 @@ int MYSQL_BIN_LOG::purge_logs(const char > goto err; > } > > - DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_SUICIDE();); > > err: > /* Read each entry from purge_index_file and delete the file. */ > @@ -2292,7 +2292,7 @@ err: > " that would be purged."); > close_purge_index_file(); > > - DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_SUICIDE();); > > if (need_mutex) > mysql_mutex_unlock(&LOCK_index); > @@ -3457,7 +3457,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C > DBUG_PRINT("info", ("error writing binlog cache: %d", > write_error)); > DBUG_PRINT("info", ("crashing before writing xid")); > - DBUG_ABORT(); > + DBUG_SUICIDE(); > }); > > if ((write_error= write_cache(cache, false, false))) > @@ -3472,7 +3472,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_C > bool synced= 0; > if (flush_and_sync(&synced)) > goto err; > - DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_ABORT();); > + DBUG_EXECUTE_IF("half_binlogged_transaction", DBUG_SUICIDE();); > if (cache->error) // Error on read > { > sql_print_error(ER(ER_ERROR_ON_READ), cache->file_name, errno); > > === modified file 'sql/handler.cc' > --- a/sql/handler.cc 2010-09-01 02:51:08 +0000 > +++ b/sql/handler.cc 2010-09-28 11:11:50 +0000 > @@ -1169,7 +1169,7 @@ int ha_commit_trans(THD *thd, bool all) > uint rw_ha_count; > bool rw_trans; > > - DBUG_EXECUTE_IF("crash_commit_before", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE();); > > /* Close all cursors that can not survive COMMIT */ > if (is_real_trans) /* not a statement commit */ > @@ -1221,7 +1221,7 @@ int ha_commit_trans(THD *thd, bool all) > } > status_var_increment(thd->status_var.ha_prepare_count); > } > - DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE();); > if (error || (is_real_trans&& xid&& > (error= !(cookie= tc_log->log_xid(thd, xid))))) > { > @@ -1229,13 +1229,13 @@ int ha_commit_trans(THD *thd, bool all) > error= 1; > goto end; > } > - DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE();); > } > error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0; > - DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE();); > if (cookie) > tc_log->unlog(cookie, xid); > - DBUG_EXECUTE_IF("crash_commit_after", DBUG_ABORT();); > + DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE();); > RUN_HOOK(transaction, after_commit, (thd, FALSE)); > end: > if (rw_trans) > > === modified file 'unittest/gunit/CMakeLists.txt' > --- a/unittest/gunit/CMakeLists.txt 2010-07-30 08:34:23 +0000 > +++ b/unittest/gunit/CMakeLists.txt 2010-09-28 11:11:50 +0000 > @@ -207,7 +207,7 @@ IF (CMAKE_CXX_COMPILER_ID STREQUAL "SunP > ENDIF() > > # Add tests (link them with sql library) > -SET(TESTS sql_list mdl mdl_mytap my_regex thread_utils) > +SET(TESTS dbug sql_list mdl mdl_mytap my_regex thread_utils) > FOREACH(test ${TESTS}) > ADD_EXECUTABLE(${test}-t ${test}-t.cc) > TARGET_LINK_LIBRARIES(${test}-t gunit sqlgunitlib strings dbug regex) > > === added file 'unittest/gunit/dbug-t.cc' > --- a/unittest/gunit/dbug-t.cc 1970-01-01 00:00:00 +0000 > +++ b/unittest/gunit/dbug-t.cc 2010-09-28 11:11:50 +0000 > @@ -0,0 +1,35 @@ > +/* 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, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ > + > +// First include (the generated) my_config.h, to get correct platform defines, > +// then gtest.h (before any other MySQL headers), to avoid min() macros etc ... > +#include "my_config.h" > +#include > + > +#include "my_global.h" > +#include "my_dbug.h" > + > +#if defined(DBUG_OFF) > +TEST(DebugTest, NoSuicide) > +{ > + DBUG_SUICIDE(); > +} > +#else > +TEST(DebugDeathTest, Suicide) > +{ > + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; > + EXPECT_DEATH_IF_SUPPORTED(DBUG_SUICIDE(), ""); > +} > +#endif > > > > > -- Jørgen Løland | Senior Software Engineer | +47 73842138 Oracle MySQL Trondheim, Norway