Commit 96c88435 authored by Alexander Nozdrin's avatar Alexander Nozdrin

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.
parent d92b2238
...@@ -1165,6 +1165,7 @@ void free_used_memory() ...@@ -1165,6 +1165,7 @@ void free_used_memory()
mysql_server_end(); mysql_server_end();
/* Don't use DBUG after mysql_server_end() */ /* Don't use DBUG after mysql_server_end() */
DBUG_VIOLATION_HELPER_LEAVE;
return; return;
} }
...@@ -2487,7 +2488,7 @@ void do_source(struct st_command *command) ...@@ -2487,7 +2488,7 @@ void do_source(struct st_command *command)
} }
dynstr_free(&ds_filename); dynstr_free(&ds_filename);
return; DBUG_VOID_RETURN;
} }
...@@ -7507,6 +7508,8 @@ static void init_signal_handling(void) ...@@ -7507,6 +7508,8 @@ static void init_signal_handling(void)
#endif #endif
sigaction(SIGILL, &sa, NULL); sigaction(SIGILL, &sa, NULL);
sigaction(SIGFPE, &sa, NULL); sigaction(SIGFPE, &sa, NULL);
DBUG_VOID_RETURN;
} }
#endif /* !__WIN__ */ #endif /* !__WIN__ */
...@@ -8121,6 +8124,8 @@ void do_get_replace_column(struct st_command *command) ...@@ -8121,6 +8124,8 @@ void do_get_replace_column(struct st_command *command)
} }
my_free(start, MYF(0)); my_free(start, MYF(0));
command->last_argument= command->end; command->last_argument= command->end;
DBUG_VOID_RETURN;
} }
......
...@@ -16,6 +16,29 @@ ...@@ -16,6 +16,29 @@
#ifndef _dbug_h #ifndef _dbug_h
#define _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 #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
...@@ -47,11 +70,31 @@ extern void _db_lock_file_(void); ...@@ -47,11 +70,31 @@ extern void _db_lock_file_(void);
extern void _db_unlock_file_(void); extern void _db_unlock_file_(void);
extern FILE *_db_fp_(void); extern FILE *_db_fp_(void);
#define DBUG_ENTER(a) const char *_db_func_, *_db_file_; uint _db_level_; \ #ifdef __cplusplus
#define DBUG_ENTER(a) \
const char *_db_func_, *_db_file_; \
uint _db_level_; \
char **_db_framep_; \ char **_db_framep_; \
_db_enter_ (a,__FILE__,__LINE__,&_db_func_,&_db_file_,&_db_level_, \ Dbug_violation_helper dbug_violation_helper; \
&_db_framep_) _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 \ #define DBUG_LEAVE \
DBUG_VIOLATION_HELPER_LEAVE; \
_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_) _db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)
#define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0) #define DBUG_RETURN(a1) do {DBUG_LEAVE; return(a1);} while(0)
#define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0) #define DBUG_VOID_RETURN do {DBUG_LEAVE; return;} while(0)
......
...@@ -4789,10 +4789,10 @@ static bool read_init_file(char *file_name) ...@@ -4789,10 +4789,10 @@ static bool read_init_file(char *file_name)
DBUG_ENTER("read_init_file"); DBUG_ENTER("read_init_file");
DBUG_PRINT("enter",("name: %s",file_name)); DBUG_PRINT("enter",("name: %s",file_name));
if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME)))) if (!(file=my_fopen(file_name,O_RDONLY,MYF(MY_WME))))
return(1); DBUG_RETURN(TRUE);
bootstrap(file); bootstrap(file);
(void) my_fclose(file,MYF(MY_WME)); (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) ...@@ -350,6 +350,7 @@ Rpl_filter::add_do_db(const char* table_spec)
DBUG_ENTER("Rpl_filter::add_do_db"); DBUG_ENTER("Rpl_filter::add_do_db");
i_string *db = new i_string(table_spec); i_string *db = new i_string(table_spec);
do_db.push_back(db); do_db.push_back(db);
DBUG_VOID_RETURN;
} }
...@@ -359,6 +360,7 @@ Rpl_filter::add_ignore_db(const char* table_spec) ...@@ -359,6 +360,7 @@ Rpl_filter::add_ignore_db(const char* table_spec)
DBUG_ENTER("Rpl_filter::add_ignore_db"); DBUG_ENTER("Rpl_filter::add_ignore_db");
i_string *db = new i_string(table_spec); i_string *db = new i_string(table_spec);
ignore_db.push_back(db); ignore_db.push_back(db);
DBUG_VOID_RETURN;
} }
extern "C" uchar *get_table_key(const uchar *, size_t *, my_bool); 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) ...@@ -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) if (bit_is_set(slave_exec_mode_options, SLAVE_EXEC_MODE_IDEMPOTENT) == 0)
bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT); bit_do_set(slave_exec_mode_options, SLAVE_EXEC_MODE_STRICT);
DBUG_VOID_RETURN;
} }
......
...@@ -2274,44 +2274,9 @@ void kill_delayed_threads(void) ...@@ -2274,44 +2274,9 @@ void kill_delayed_threads(void)
} }
/* static void handle_delayed_insert_impl(THD *thd, Delayed_insert *di)
* Create a new delayed insert thread
*/
pthread_handler_t handle_delayed_insert(void *arg)
{ {
Delayed_insert *di=(Delayed_insert*) arg; DBUG_ENTER("handle_delayed_insert_impl");
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");
thd->thread_stack= (char*) &thd; thd->thread_stack= (char*) &thd;
if (init_thr_lock() || thd->store_globals()) if (init_thr_lock() || thd->store_globals())
{ {
...@@ -2500,6 +2465,49 @@ err: ...@@ -2500,6 +2465,49 @@ err:
*/ */
ha_autocommit_or_rollback(thd, 1); 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__ #ifndef __WIN__
end: end:
#endif #endif
...@@ -2523,7 +2531,8 @@ end: ...@@ -2523,7 +2531,8 @@ end:
my_thread_end(); my_thread_end();
pthread_exit(0); pthread_exit(0);
DBUG_RETURN(0);
return 0;
} }
......
...@@ -408,29 +408,12 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var, ...@@ -408,29 +408,12 @@ void execute_init_command(THD *thd, sys_var_str *init_command_var,
} }
/** static void handle_bootstrap_impl(THD *thd)
Execute commands from bootstrap_file.
Used when creating the initial grant tables.
*/
pthread_handler_t handle_bootstrap(void *arg)
{ {
THD *thd=(THD*) arg;
FILE *file=bootstrap_file; FILE *file=bootstrap_file;
char *buff; char *buff;
const char* found_semicolon= NULL; 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"); DBUG_ENTER("handle_bootstrap");
#ifndef EMBEDDED_LIBRARY #ifndef EMBEDDED_LIBRARY
...@@ -525,6 +508,33 @@ pthread_handler_t handle_bootstrap(void *arg) ...@@ -525,6 +508,33 @@ pthread_handler_t handle_bootstrap(void *arg)
#endif #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: end:
net_end(&thd->net); net_end(&thd->net);
thd->cleanup(); thd->cleanup();
...@@ -539,7 +549,8 @@ end: ...@@ -539,7 +549,8 @@ end:
my_thread_end(); my_thread_end();
pthread_exit(0); pthread_exit(0);
#endif #endif
DBUG_RETURN(0);
return 0;
} }
......
...@@ -274,7 +274,7 @@ Suma::execSTTOR(Signal* signal) { ...@@ -274,7 +274,7 @@ Suma::execSTTOR(Signal* signal) {
jam(); jam();
send_start_me_req(signal); send_start_me_req(signal);
return; DBUG_VOID_RETURN;
} }
} }
...@@ -322,7 +322,7 @@ Suma::execSTTOR(Signal* signal) { ...@@ -322,7 +322,7 @@ Suma::execSTTOR(Signal* signal) {
if (ERROR_INSERTED(13030)) if (ERROR_INSERTED(13030))
{ {
ndbout_c("Dont start handover"); ndbout_c("Dont start handover");
return; DBUG_VOID_RETURN;
} }
}//if }//if
...@@ -332,7 +332,7 @@ Suma::execSTTOR(Signal* signal) { ...@@ -332,7 +332,7 @@ Suma::execSTTOR(Signal* signal) {
* Allow API's to connect * Allow API's to connect
*/ */
sendSTTORRY(signal); sendSTTORRY(signal);
return; DBUG_VOID_RETURN;
} }
if(startphase == 101) if(startphase == 101)
...@@ -345,7 +345,7 @@ Suma::execSTTOR(Signal* signal) { ...@@ -345,7 +345,7 @@ Suma::execSTTOR(Signal* signal) {
*/ */
c_startup.m_wait_handover= true; c_startup.m_wait_handover= true;
check_start_handover(signal); check_start_handover(signal);
return; DBUG_VOID_RETURN;
} }
} }
sendSTTORRY(signal); sendSTTORRY(signal);
...@@ -575,19 +575,19 @@ void Suma::execAPI_FAILREQ(Signal* signal) ...@@ -575,19 +575,19 @@ void Suma::execAPI_FAILREQ(Signal* signal)
jam(); jam();
sendSignalWithDelay(reference(), GSN_API_FAILREQ, signal, sendSignalWithDelay(reference(), GSN_API_FAILREQ, signal,
200, signal->getLength()); 200, signal->getLength());
return; DBUG_VOID_RETURN;
} }
if (c_failedApiNodes.get(failedApiNode)) if (c_failedApiNodes.get(failedApiNode))
{ {
jam(); jam();
return; DBUG_VOID_RETURN;
} }
if (!c_subscriber_nodes.get(failedApiNode)) if (!c_subscriber_nodes.get(failedApiNode))
{ {
jam(); jam();
return; DBUG_VOID_RETURN;
} }
c_failedApiNodes.set(failedApiNode); c_failedApiNodes.set(failedApiNode);
...@@ -2453,7 +2453,7 @@ Suma::execSUB_START_REQ(Signal* signal){ ...@@ -2453,7 +2453,7 @@ Suma::execSUB_START_REQ(Signal* signal){
jam(); jam();
c_subscriberPool.release(subbPtr); c_subscriberPool.release(subbPtr);
sendSubStartRef(signal, SubStartRef::PartiallyConnected); sendSubStartRef(signal, SubStartRef::PartiallyConnected);
return; DBUG_VOID_RETURN;
} }
DBUG_PRINT("info",("c_subscriberPool size: %d free: %d", DBUG_PRINT("info",("c_subscriberPool size: %d free: %d",
...@@ -4289,7 +4289,7 @@ Suma::Restart::runSUMA_START_ME_REQ(Signal* signal, Uint32 sumaRef) ...@@ -4289,7 +4289,7 @@ Suma::Restart::runSUMA_START_ME_REQ(Signal* signal, Uint32 sumaRef)
ref->errorCode = SumaStartMeRef::Busy; ref->errorCode = SumaStartMeRef::Busy;
suma.sendSignal(sumaRef, GSN_SUMA_START_ME_REF, signal, suma.sendSignal(sumaRef, GSN_SUMA_START_ME_REF, signal,
SumaStartMeRef::SignalLength, JBB); SumaStartMeRef::SignalLength, JBB);
return; DBUG_VOID_RETURN;
} }
nodeId = refToNode(sumaRef); nodeId = refToNode(sumaRef);
......
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