#At file:///export/home/didrik/repo/next-mr-bf-binlogcore/ based on revid:alik@stripped
3305 Tor Didriksen 2010-09-29
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-29 07:24:36 +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-28 15:30:47 +0000
+++ b/sql/binlog.cc 2010-09-29 07:24:36 +0000
@@ -1572,7 +1572,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;
@@ -1672,7 +1672,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);
@@ -1691,7 +1691,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
}
}
@@ -2143,7 +2143,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,
@@ -2271,7 +2271,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()))
{
@@ -2286,7 +2286,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. */
@@ -2296,7 +2296,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);
@@ -3461,7 +3461,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)))
@@ -3476,7 +3476,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-29 07:24:36 +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-29 07:24:36 +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-29 07:24:36 +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
Attachment: [text/bzr-bundle] bzr/tor.didriksen@oracle.com-20100929072436-wuwa63qprsy5w7hz.bundle