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<sys/types.h>
> +#endif
> +
> +#ifndef __WIN__
> +#include<signal.h>
> +#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<gtest/gtest.h>
> +
> +#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