mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 03:52:35 +01:00
A patch for Bug#45118 (mysqld.exe crashed in debug mode
on Windows in dbug.c) -- part 2: a patch for the DBUG subsystem to detect misuse of DBUG_ENTER / DBUG_RETURN macros. 5.1 version.
This commit is contained in:
parent
0d7ee91c61
commit
70972926ab
8 changed files with 144 additions and 73 deletions
|
@ -1165,6 +1165,7 @@ void free_used_memory()
|
|||
mysql_server_end();
|
||||
|
||||
/* Don't use DBUG after mysql_server_end() */
|
||||
DBUG_VIOLATION_HELPER_LEAVE;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -2487,7 +2488,7 @@ void do_source(struct st_command *command)
|
|||
}
|
||||
|
||||
dynstr_free(&ds_filename);
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -7507,6 +7508,8 @@ static void init_signal_handling(void)
|
|||
#endif
|
||||
sigaction(SIGILL, &sa, NULL);
|
||||
sigaction(SIGFPE, &sa, NULL);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
#endif /* !__WIN__ */
|
||||
|
@ -8121,6 +8124,8 @@ void do_get_replace_column(struct st_command *command)
|
|||
}
|
||||
my_free(start, MYF(0));
|
||||
command->last_argument= command->end;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -16,6 +16,29 @@
|
|||
#ifndef _dbug_h
|
||||
#define _dbug_h
|
||||
|
||||
#if defined(__cplusplus) && !defined(DBUG_OFF)
|
||||
class Dbug_violation_helper
|
||||
{
|
||||
public:
|
||||
inline Dbug_violation_helper() :
|
||||
_entered(TRUE)
|
||||
{ }
|
||||
|
||||
inline ~Dbug_violation_helper()
|
||||
{
|
||||
assert(!_entered);
|
||||
}
|
||||
|
||||
inline void leave()
|
||||
{
|
||||
_entered= FALSE;
|
||||
}
|
||||
|
||||
private:
|
||||
bool _entered;
|
||||
};
|
||||
#endif /* C++ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -47,11 +70,31 @@ extern void _db_lock_file_(void);
|
|||
extern void _db_unlock_file_(void);
|
||||
extern FILE *_db_fp_(void);
|
||||
|
||||
#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \
|
||||
char **_db_framep_; \
|
||||
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \
|
||||
&_db_framep_)
|
||||
#ifdef __cplusplus
|
||||
|
||||
#define DBUG_ENTER(a) \
|
||||
const char *_db_func_, *_db_file_; \
|
||||
uint _db_level_; \
|
||||
char **_db_framep_; \
|
||||
Dbug_violation_helper dbug_violation_helper; \
|
||||
_db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \
|
||||
&_db_level_, &_db_framep_)
|
||||
#define DBUG_VIOLATION_HELPER_LEAVE dbug_violation_helper.leave()
|
||||
|
||||
#else /* C */
|
||||
|
||||
#define DBUG_ENTER(a) \
|
||||
const char *_db_func_, *_db_file_; \
|
||||
uint _db_level_; \
|
||||
char **_db_framep_; \
|
||||
_db_enter_ (a, __FILE__, __LINE__, &_db_func_, &_db_file_, \
|
||||
&_db_level_, &_db_framep_)
|
||||
#define DBUG_VIOLATION_HELPER_LEAVE do { } while(0)
|
||||
|
||||
#endif /* C++ */
|
||||
|
||||
#define DBUG_LEAVE \
|
||||
DBUG_VIOLATION_HELPER_LEAVE; \
|
||||
_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)
|
||||
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
|
||||
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
|
||||
|
|
|
@ -4789,10 +4789,10 @@ static bool read_init_file(char *file_name)
|
|||
DBUG_ENTER("read_init_file");
|
||||
DBUG_PRINT("enter",("name: %s",file_name));
|
||||
if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
|
||||
return(1);
|
||||
DBUG_RETURN(TRUE);
|
||||
bootstrap(file);
|
||||
(void) my_fclose(file,MYF(MY_WME));
|
||||
return 0;
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -350,6 +350,7 @@ Rpl_filter::add_do_db(const char* table_spec)
|
|||
DBUG_ENTER("Rpl_filter::add_do_db");
|
||||
i_string *db = new i_string(table_spec);
|
||||
do_db.push_back(db);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
@ -359,6 +360,7 @@ Rpl_filter::add_ignore_db(const char* table_spec)
|
|||
DBUG_ENTER("Rpl_filter::add_ignore_db");
|
||||
i_string *db = new i_string(table_spec);
|
||||
ignore_db.push_back(db);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
extern "C" uchar *get_table_key(const uchar *, size_t *, my_bool);
|
||||
|
|
|
@ -1238,6 +1238,7 @@ void fix_slave_exec_mode(enum_var_type type)
|
|||
}
|
||||
if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
|
||||
bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2274,44 +2274,9 @@ void kill_delayed_threads(void)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new delayed insert thread
|
||||
*/
|
||||
|
||||
pthread_handler_t handle_delayed_insert(void *arg)
|
||||
static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
|
||||
{
|
||||
Delayed_insert *di=(Delayed_insert*) arg;
|
||||
THD *thd= &di->thd;
|
||||
|
||||
pthread_detach_this_thread();
|
||||
/* Add thread to THD list so that's it's visible in 'show processlist' */
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
thd->set_current_time();
|
||||
threads.append(thd);
|
||||
thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/*
|
||||
Wait until the client runs into pthread_cond_wait(),
|
||||
where we free it after the table is opened and di linked in the list.
|
||||
If we did not wait here, the client might detect the opened table
|
||||
before it is linked to the list. It would release LOCK_delayed_create
|
||||
and allow another thread to create another handler for the same table,
|
||||
since it does not find one in the list.
|
||||
*/
|
||||
pthread_mutex_lock(&di->mutex);
|
||||
#if !defined( __WIN__) /* Win32 calls this in pthread_create */
|
||||
if (my_thread_init())
|
||||
{
|
||||
/* Can't use my_error since store_globals has not yet been called */
|
||||
thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
|
||||
ER(ER_OUT_OF_RESOURCES));
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
DBUG_ENTER("handle_delayed_insert");
|
||||
DBUG_ENTER("handle_delayed_insert_impl");
|
||||
thd->thread_stack= (char*) &thd;
|
||||
if (init_thr_lock() || thd->store_globals())
|
||||
{
|
||||
|
@ -2500,6 +2465,49 @@ err:
|
|||
*/
|
||||
ha_autocommit_or_rollback(thd, 1);
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new delayed insert thread
|
||||
*/
|
||||
|
||||
pthread_handler_t handle_delayed_insert(void *arg)
|
||||
{
|
||||
Delayed_insert *di=(Delayed_insert*) arg;
|
||||
THD *thd= &di->thd;
|
||||
|
||||
pthread_detach_this_thread();
|
||||
/* Add thread to THD list so that's it's visible in 'show processlist' */
|
||||
pthread_mutex_lock(&LOCK_thread_count);
|
||||
thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
|
||||
thd->set_current_time();
|
||||
threads.append(thd);
|
||||
thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
|
||||
/*
|
||||
Wait until the client runs into pthread_cond_wait(),
|
||||
where we free it after the table is opened and di linked in the list.
|
||||
If we did not wait here, the client might detect the opened table
|
||||
before it is linked to the list. It would release LOCK_delayed_create
|
||||
and allow another thread to create another handler for the same table,
|
||||
since it does not find one in the list.
|
||||
*/
|
||||
pthread_mutex_lock(&di->mutex);
|
||||
#if !defined( __WIN__) /* Win32 calls this in pthread_create */
|
||||
if (my_thread_init())
|
||||
{
|
||||
/* Can't use my_error since store_globals has not yet been called */
|
||||
thd->main_da.set_error_status(thd, ER_OUT_OF_RESOURCES,
|
||||
ER(ER_OUT_OF_RESOURCES));
|
||||
goto end;
|
||||
}
|
||||
#endif
|
||||
|
||||
handle_delayed_insert_impl(thd, di);
|
||||
|
||||
#ifndef __WIN__
|
||||
end:
|
||||
#endif
|
||||
|
@ -2523,7 +2531,8 @@ end:
|
|||
|
||||
my_thread_end();
|
||||
pthread_exit(0);
|
||||
DBUG_RETURN(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -408,29 +408,12 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
Execute commands from bootstrap_file.
|
||||
|
||||
Used when creating the initial grant tables.
|
||||
*/
|
||||
|
||||
pthread_handler_t handle_bootstrap(void *arg)
|
||||
static void handle_bootstrap_impl(THD *thd)
|
||||
{
|
||||
THD *thd=(THD*) arg;
|
||||
FILE *file=bootstrap_file;
|
||||
char *buff;
|
||||
const char* found_semicolon= NULL;
|
||||
|
||||
/* The following must be called before DBUG_ENTER */
|
||||
thd->thread_stack= (char*) &thd;
|
||||
if (my_thread_init() || thd->store_globals())
|
||||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
||||
#endif
|
||||
thd->fatal_error();
|
||||
goto end;
|
||||
}
|
||||
DBUG_ENTER("handle_bootstrap");
|
||||
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
|
@ -525,6 +508,33 @@ pthread_handler_t handle_bootstrap(void *arg)
|
|||
#endif
|
||||
}
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Execute commands from bootstrap_file.
|
||||
|
||||
Used when creating the initial grant tables.
|
||||
*/
|
||||
|
||||
pthread_handler_t handle_bootstrap(void *arg)
|
||||
{
|
||||
THD *thd=(THD*) arg;
|
||||
|
||||
/* The following must be called before DBUG_ENTER */
|
||||
thd->thread_stack= (char*) &thd;
|
||||
if (my_thread_init() || thd->store_globals())
|
||||
{
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
close_connection(thd, ER_OUT_OF_RESOURCES, 1);
|
||||
#endif
|
||||
thd->fatal_error();
|
||||
goto end;
|
||||
}
|
||||
|
||||
handle_bootstrap_impl(thd);
|
||||
|
||||
end:
|
||||
net_end(&thd->net);
|
||||
thd->cleanup();
|
||||
|
@ -539,7 +549,8 @@ end:
|
|||
my_thread_end();
|
||||
pthread_exit(0);
|
||||
#endif
|
||||
DBUG_RETURN(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -274,7 +274,7 @@ Suma::execSTTOR(Signal* signal) {
|
|||
jam();
|
||||
|
||||
send_start_me_req(signal);
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,7 +322,7 @@ Suma::execSTTOR(Signal* signal) {
|
|||
if (ERROR_INSERTED(13030))
|
||||
{
|
||||
ndbout_c("Dont start handover");
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}//if
|
||||
|
||||
|
@ -332,7 +332,7 @@ Suma::execSTTOR(Signal* signal) {
|
|||
* Allow API's to connect
|
||||
*/
|
||||
sendSTTORRY(signal);
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
if(startphase == 101)
|
||||
|
@ -345,7 +345,7 @@ Suma::execSTTOR(Signal* signal) {
|
|||
*/
|
||||
c_startup.m_wait_handover= true;
|
||||
check_start_handover(signal);
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
}
|
||||
sendSTTORRY(signal);
|
||||
|
@ -575,19 +575,19 @@ void Suma::execAPI_FAILREQ(Signal* signal)
|
|||
jam();
|
||||
sendSignalWithDelay(reference(), GSN_API_FAILREQ, signal,
|
||||
200, signal->getLength());
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
if (c_failedApiNodes.get(failedApiNode))
|
||||
{
|
||||
jam();
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
if (!c_subscriber_nodes.get(failedApiNode))
|
||||
{
|
||||
jam();
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
c_failedApiNodes.set(failedApiNode);
|
||||
|
@ -2453,7 +2453,7 @@ Suma::execSUB_START_REQ(Signal* signal){
|
|||
jam();
|
||||
c_subscriberPool.release(subbPtr);
|
||||
sendSubStartRef(signal, SubStartRef::PartiallyConnected);
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
DBUG_PRINT("info",("c_subscriberPool size: %d free: %d",
|
||||
|
@ -4289,7 +4289,7 @@ Suma::Restart::runSUMA_START_ME_REQ(Signal* signal, Uint32 sumaRef)
|
|||
ref->errorCode = SumaStartMeRef::Busy;
|
||||
suma.sendSignal(sumaRef, GSN_SUMA_START_ME_REF, signal,
|
||||
SumaStartMeRef::SignalLength, JBB);
|
||||
return;
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
nodeId = refToNode(sumaRef);
|
||||
|
|
Loading…
Reference in a new issue