Commit 9916f14b authored by marko@hundin.mysql.fi's avatar marko@hundin.mysql.fi

InnoDB: Improved the handling of assertions.

parent 1f865775
......@@ -13,72 +13,79 @@ Created 1/30/1994 Heikki Tuuri
#include <stdlib.h>
#include "os0thread.h"
extern ibool ut_dbg_stop_threads;
#if defined(__GNUC__) && (__GNUC__ > 2)
# define UT_DBG_FAIL(EXPR) UNIV_UNLIKELY(!((ulint)(EXPR)))
#else
extern ulint ut_dbg_zero; /* This is used to eliminate
compiler warnings */
# define UT_DBG_FAIL(EXPR) !((ulint)(EXPR) + ut_dbg_zero)
#endif
extern ulint* ut_dbg_null_ptr;
/*****************************************************************
Report a failed assertion. */
void
ut_dbg_assertion_failed(
/*====================*/
const char* expr, /* in: the failed assertion */
const char* file, /* in: source file containing the assertion */
ulint line); /* in: line number of the assertion */
extern const char* ut_dbg_msg_assert_fail;
extern const char* ut_dbg_msg_trap;
extern const char* ut_dbg_msg_stop;
/* Have a graceful exit on NetWare rather than a segfault to avoid abends */
#ifdef __NETWARE__
/* Flag for ignoring further assertion failures.
On NetWare, have a graceful exit rather than a segfault to avoid abends. */
extern ibool panic_shutdown;
#define ut_a(EXPR) do {\
if (UNIV_UNLIKELY(!((ulint)(EXPR)))) {\
ut_print_timestamp(stderr);\
fprintf(stderr, ut_dbg_msg_assert_fail,\
os_thread_pf(os_thread_get_curr_id()), __FILE__,\
(ulint)__LINE__);\
fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\
fputs(ut_dbg_msg_trap, stderr);\
ut_dbg_stop_threads = TRUE;\
if (ut_dbg_stop_threads) {\
fprintf(stderr, ut_dbg_msg_stop,\
os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
}\
if(!panic_shutdown){\
panic_shutdown = TRUE;\
innobase_shutdown_for_mysql();}\
exit(1);\
}\
} while (0)
#define ut_error do {\
ut_print_timestamp(stderr);\
fprintf(stderr, ut_dbg_msg_assert_fail,\
os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
fprintf(stderr, ut_dbg_msg_trap);\
ut_dbg_stop_threads = TRUE;\
if(!panic_shutdown){panic_shutdown = TRUE;\
innobase_shutdown_for_mysql();}\
} while (0)
#else
#define ut_a(EXPR) do {\
if (UNIV_UNLIKELY(!((ulint)(EXPR)))) {\
ut_print_timestamp(stderr);\
fprintf(stderr, ut_dbg_msg_assert_fail,\
os_thread_pf(os_thread_get_curr_id()), __FILE__,\
(ulint)__LINE__);\
fputs("InnoDB: Failing assertion: " #EXPR "\n", stderr);\
fputs(ut_dbg_msg_trap, stderr);\
ut_dbg_stop_threads = TRUE;\
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\
}\
if (ut_dbg_stop_threads) {\
fprintf(stderr, ut_dbg_msg_stop,\
os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
os_thread_sleep(1000000000);\
}\
/* Abort the execution. */
# define UT_DBG_PANIC \
if (!panic_shutdown){ \
panic_shutdown = TRUE; \
innobase_shutdown_for_mysql(); \
} \
exit(1)
/* Stop threads in ut_a(). */
# define UT_DBG_STOP while (0) /* We do not do this on NetWare */
#else /* __NETWARE__ */
/* Flag for indicating that all threads should stop. This will be set
by ut_dbg_assertion_failed(). */
extern ibool ut_dbg_stop_threads;
/* A null pointer that will be dereferenced to trigger a memory trap */
extern ulint* ut_dbg_null_ptr;
/*****************************************************************
Stop a thread after assertion failure. */
void
ut_dbg_stop_thread(
/*===============*/
const char* file,
ulint line);
/* Abort the execution. */
# define UT_DBG_PANIC \
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL
/* Stop threads in ut_a(). */
# define UT_DBG_STOP do \
if (UNIV_UNLIKELY(ut_dbg_stop_threads)) { \
ut_dbg_stop_thread(__FILE__, (ulint) __LINE__); \
} while (0)
#endif /* __NETWARE__ */
/* Abort execution if EXPR does not evaluate to nonzero. */
#define ut_a(EXPR) do { \
if (UT_DBG_FAIL(EXPR)) { \
ut_dbg_assertion_failed(#EXPR, \
__FILE__, (ulint) __LINE__); \
UT_DBG_PANIC; \
} \
UT_DBG_STOP; \
} while (0)
#define ut_error do {\
ut_print_timestamp(stderr);\
fprintf(stderr, ut_dbg_msg_assert_fail,\
os_thread_pf(os_thread_get_curr_id()), __FILE__, (ulint)__LINE__);\
fprintf(stderr, ut_dbg_msg_trap);\
ut_dbg_stop_threads = TRUE;\
if (*(ut_dbg_null_ptr)) ut_dbg_null_ptr = NULL;\
/* Abort execution. */
#define ut_error do { \
ut_dbg_assertion_failed(0, __FILE__, (ulint) __LINE__); \
UT_DBG_PANIC; \
} while (0)
#endif
#ifdef UNIV_DEBUG
#define ut_ad(EXPR) ut_a(EXPR)
......
......@@ -8,6 +8,12 @@ Created 1/30/1994 Heikki Tuuri
#include "univ.i"
#if defined(__GNUC__) && (__GNUC__ > 2)
#else
/* This is used to eliminate compiler warnings */
ulint ut_dbg_zero = 0;
#endif
/* If this is set to TRUE all threads will stop into the next assertion
and assert */
ibool ut_dbg_stop_threads = FALSE;
......@@ -16,21 +22,55 @@ ibool panic_shutdown = FALSE; /* This is set to TRUE when on NetWare there
happens an InnoDB assertion failure or other
fatal error condition that requires an
immediate shutdown. */
#endif
#else /* __NETWARE__ */
/* Null pointer used to generate memory trap */
ulint* ut_dbg_null_ptr = NULL;
#endif /* __NETWARE__ */
const char* ut_dbg_msg_assert_fail =
"InnoDB: Assertion failure in thread %lu in file %s line %lu\n";
const char* ut_dbg_msg_trap =
/*****************************************************************
Report a failed assertion. */
void
ut_dbg_assertion_failed(
/*====================*/
const char* expr, /* in: the failed assertion (optional) */
const char* file, /* in: source file containing the assertion */
ulint line) /* in: line number of the assertion */
{
ut_print_timestamp(stderr);
fprintf(stderr,
"InnoDB: Assertion failure in thread %lu"
" in file %s line %lu\n",
os_thread_pf(os_thread_get_curr_id()), file, line);
if (expr) {
fprintf(stderr,
"InnoDB: Failing assertion: %s\n", expr);
}
fputs(
"InnoDB: We intentionally generate a memory trap.\n"
"InnoDB: Submit a detailed bug report to http://bugs.mysql.com.\n"
"InnoDB: If you get repeated assertion failures or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
"InnoDB: http://dev.mysql.com/doc/mysql/en/Forcing_recovery.html\n"
"InnoDB: about forcing recovery.\n";
"InnoDB: about forcing recovery.\n", stderr);
ut_dbg_stop_threads = TRUE;
}
#ifndef __NETWARE__
/*****************************************************************
Stop a thread after assertion failure. */
const char* ut_dbg_msg_stop =
"InnoDB: Thread %lu stopped in file %s line %lu\n";
void
ut_dbg_stop_thread(
/*===============*/
const char* file,
ulint line)
{
fprintf(stderr, "InnoDB: Thread %lu stopped in file %s line %lu\n",
os_thread_pf(os_thread_get_curr_id()), file, line);
os_thread_sleep(1000000000);
}
#endif /* __NETWARE__ */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment