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:
Alexander Nozdrin 2009-09-10 11:40:57 +04:00
parent 0d7ee91c61
commit 70972926ab
8 changed files with 144 additions and 73 deletions

View file

@ -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;
}

View file

@ -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_; \
#ifdef __cplusplus
#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_)
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)

View file

@ -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);
}

View file

@ -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);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);