summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dbug/dbug.c8
-rw-r--r--include/my_dbug.h51
-rw-r--r--sql/handler.cc10
-rw-r--r--sql/log.cc18
4 files changed, 69 insertions, 18 deletions
diff --git a/dbug/dbug.c b/dbug/dbug.c
index 76723fa8767..7278acca2a9 100644
--- a/dbug/dbug.c
+++ b/dbug/dbug.c
@@ -2267,6 +2267,14 @@ static void dbug_flush(CODE_STATE *cs)
} /* dbug_flush */
+void _db_flush_()
+{
+ CODE_STATE *cs;
+ get_code_state_or_return;
+ (void) fflush(cs->stack->out_file);
+}
+
+
void _db_lock_file_()
{
CODE_STATE *cs=0;
diff --git a/include/my_dbug.h b/include/my_dbug.h
index 0ba72b2210d..f08e94a1882 100644
--- a/include/my_dbug.h
+++ b/include/my_dbug.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* 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
@@ -13,8 +13,18 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#ifndef _dbug_h
-#define _dbug_h
+#ifndef MY_DBUG_INCLUDED
+#define MY_DBUG_INCLUDED
+
+#ifndef __WIN__
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <signal.h>
+#endif /* not __WIN__ */
#if defined(__cplusplus) && !defined(DBUG_OFF)
class Dbug_violation_helper
@@ -69,6 +79,7 @@ extern void _db_end_(void);
extern void _db_lock_file_(void);
extern void _db_unlock_file_(void);
extern FILE *_db_fp_(void);
+extern void _db_flush_();
#ifdef __cplusplus
@@ -124,6 +135,34 @@ extern FILE *_db_fp_(void);
#define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len))
#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len))
#define IF_DBUG(A) A
+#ifndef __WIN__
+#define DBUG_ABORT() (_db_flush_(), abort())
+#else
+/*
+ Avoid popup with abort/retry/ignore buttons. When BUG#31745 is fixed we can
+ call abort() instead of _exit(3) (now it would cause a "test signal" popup).
+*/
+#include <crtdbg.h>
+#define DBUG_ABORT() (_db_flush_(),\
+ (void)_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE),\
+ (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR),\
+ _exit(3))
+#endif
+
+/*
+ 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.
+ We also pause the current thread, until the signal is actually delivered.
+ 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), pause())
+#endif
+
#else /* No debugger */
#define DBUG_ENTER(a1)
@@ -152,8 +191,12 @@ extern FILE *_db_fp_(void);
#define DBUG_EXPLAIN(buf,len)
#define DBUG_EXPLAIN_INITIAL(buf,len)
#define IF_DBUG(A)
+#define DBUG_ABORT() do { } while(0)
+#define DBUG_SUICIDE() do { } while(0)
+
#endif
#ifdef __cplusplus
}
#endif
-#endif
+
+#endif /* MY_DBUG_INCLUDED */
diff --git a/sql/handler.cc b/sql/handler.cc
index 19f397ef09f..a47a5fd8a3c 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1127,7 +1127,7 @@ int ha_commit_trans(THD *thd, bool all)
uint rw_ha_count;
bool rw_trans;
- DBUG_EXECUTE_IF("crash_commit_before", 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 */
@@ -1179,7 +1179,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", abort(););
+ DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
if (error || (is_real_trans && xid &&
(error= !(cookie= tc_log->log_xid(thd, xid)))))
{
@@ -1187,13 +1187,13 @@ int ha_commit_trans(THD *thd, bool all)
error= 1;
goto end;
}
- DBUG_EXECUTE_IF("crash_commit_after_log", 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", abort(););
+ DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE(););
if (cookie)
tc_log->unlog(cookie, xid);
- DBUG_EXECUTE_IF("crash_commit_after", abort(););
+ DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
end:
if (rw_trans)
start_waiting_global_read_lock(thd);
diff --git a/sql/log.cc b/sql/log.cc
index 56f151fe2ab..2d5b62a5b2b 100644
--- a/sql/log.cc
+++ b/sql/log.cc
@@ -2600,7 +2600,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
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", abort(););
+ DBUG_EXECUTE_IF("crash_create_non_critical_before_update_index", DBUG_SUICIDE(););
#endif
write_error= 0;
@@ -2697,7 +2697,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
if (write_file_name_to_index_file)
{
#ifdef HAVE_REPLICATION
- DBUG_EXECUTE_IF("crash_create_critical_before_update_index", abort(););
+ DBUG_EXECUTE_IF("crash_create_critical_before_update_index", DBUG_SUICIDE(););
#endif
DBUG_ASSERT(my_b_inited(&index_file) != 0);
@@ -2716,7 +2716,7 @@ bool MYSQL_BIN_LOG::open(const char *log_name,
goto err;
#ifdef HAVE_REPLICATION
- DBUG_EXECUTE_IF("crash_create_after_update_index", abort(););
+ DBUG_EXECUTE_IF("crash_create_after_update_index", DBUG_SUICIDE(););
#endif
}
}
@@ -3168,7 +3168,7 @@ int MYSQL_BIN_LOG::purge_first_log(Relay_log_info* rli, bool included)
/* Store where we are in the new file for the execution thread */
flush_relay_log_info(rli);
- DBUG_EXECUTE_IF("crash_before_purge_logs", abort(););
+ DBUG_EXECUTE_IF("crash_before_purge_logs", DBUG_SUICIDE(););
pthread_mutex_lock(&rli->log_space_lock);
rli->relay_log.purge_logs(to_purge_if_included, included,
@@ -3296,7 +3296,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
break;
}
- DBUG_EXECUTE_IF("crash_purge_before_update_index", abort(););
+ DBUG_EXECUTE_IF("crash_purge_before_update_index", DBUG_SUICIDE(););
if ((error= sync_purge_index_file()))
{
@@ -3311,7 +3311,7 @@ int MYSQL_BIN_LOG::purge_logs(const char *to_log,
goto err;
}
- DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", abort(););
+ DBUG_EXECUTE_IF("crash_purge_critical_after_update_index", DBUG_SUICIDE(););
err:
/* Read each entry from purge_index_file and delete the file. */
@@ -3321,7 +3321,7 @@ err:
" that would be purged.");
close_purge_index_file();
- DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", abort(););
+ DBUG_EXECUTE_IF("crash_purge_non_critical_after_update_index", DBUG_SUICIDE(););
if (need_mutex)
pthread_mutex_unlock(&LOCK_index);
@@ -4832,7 +4832,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event,
DBUG_PRINT("info", ("error writing binlog cache: %d",
write_error));
DBUG_PRINT("info", ("crashing before writing xid"));
- abort();
+ DBUG_SUICIDE();
});
if ((write_error= write_cache(cache, false, false)))
@@ -4846,7 +4846,7 @@ bool MYSQL_BIN_LOG::write(THD *thd, IO_CACHE *cache, Log_event *commit_event,
if (flush_and_sync())
goto err;
- DBUG_EXECUTE_IF("half_binlogged_transaction", 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);