diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index b1a931a9df1c49ecae06e0590dc4619059752729..60b54a2ed994761a0d05149a5e9d2d33ce1a1aac 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -788,7 +788,8 @@ static void die(const char* fmt, ...) fprintf(stderr, "\n"); va_end(args); cleanup(); - my_end(0); + /* We cannot free DBUG, it is used in global destructors after exit(). */ + my_end(MY_DONT_FREE_DBUG); exit(1); } @@ -1460,7 +1461,8 @@ int main(int argc, char** argv) cleanup(); free_defaults(defaults_argv); my_free_open_file_info(); - my_end(0); + /* We cannot free DBUG, it is used in global destructors after exit(). */ + my_end(MY_DONT_FREE_DBUG); exit(exit_value); DBUG_RETURN(exit_value); // Keep compilers happy } diff --git a/dbug/dbug.c b/dbug/dbug.c index 91b7e7b6c4c8bf27968eac9411eaf007ba58a82a..c991daf3617711b705862d6db3264fcffa099c9d 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -271,6 +271,8 @@ static unsigned long Clock (void); static void CloseFile(FILE *fp); /* Push current debug state */ static void PushState(void); + /* Free memory associated with debug state. */ +static void FreeState (struct state *state); /* Test for tracing enabled */ static BOOLEAN DoTrace(CODE_STATE *state); /* Test to see if file is writable */ @@ -630,22 +632,7 @@ void _db_pop_ () stack = discard -> next_state; _db_fp_ = stack -> out_file; _db_pfp_ = stack -> prof_file; - if (discard -> keywords != NULL) { - FreeList (discard -> keywords); - } - if (discard -> functions != NULL) { - FreeList (discard -> functions); - } - if (discard -> processes != NULL) { - FreeList (discard -> processes); - } - if (discard -> p_functions != NULL) { - FreeList (discard -> p_functions); - } - CloseFile (discard -> out_file); - if (discard -> prof_file) - CloseFile (discard -> prof_file); - free ((char *) discard); + FreeState(discard); if (!(stack->flags & DEBUG_ON)) _db_on_=0; } @@ -1160,6 +1147,71 @@ static void PushState () stack=new_malloc; } +/* + * FUNCTION + * + * FreeState Free memory associated with a struct state. + * + * SYNOPSIS + * + * static void FreeState (state) + * struct state *state; + * + * DESCRIPTION + * + * Deallocates the memory allocated for various information in a + * state. + * + */ +static void FreeState ( +struct state *state) +{ + if (state -> keywords != NULL) { + FreeList (state -> keywords); + } + if (state -> functions != NULL) { + FreeList (state -> functions); + } + if (state -> processes != NULL) { + FreeList (state -> processes); + } + if (state -> p_functions != NULL) { + FreeList (state -> p_functions); + } + CloseFile (state -> out_file); + if (state -> prof_file) + CloseFile (state -> prof_file); + free ((char *) state); +} + + +/* + * FUNCTION + * + * _db_end_ End debugging, freeing state stack memory. + * + * SYNOPSIS + * + * static VOID _db_end_ () + * + * DESCRIPTION + * + * Ends debugging, de-allocating the memory allocated to the + * state stack. + * + * To be called at the very end of the program. + * + */ +void _db_end_ () +{ + reg1 struct state *discard; + while((discard= stack) != NULL) { + stack= discard -> next_state; + FreeState (discard); + } + _db_on_=0; +} + /* * FUNCTION diff --git a/include/my_dbug.h b/include/my_dbug.h index b76a3fcc8c97636735a45bc25bd580bdd2526713..6e60b599f531277c354bea17281c1b387626af61 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -40,6 +40,7 @@ extern void _db_doprnt_ _VARARGS((const char *format,...)); extern void _db_dump_(uint _line_,const char *keyword,const char *memory, uint length); extern void _db_output_(uint flag); +extern void _db_end_(void); extern void _db_lock_file(void); extern void _db_unlock_file(void); @@ -66,6 +67,7 @@ extern void _db_unlock_file(void); #define DBUG_IN_USE (_db_fp_ && _db_fp_ != stderr) #define DEBUGGER_OFF _no_db_=1;_db_on_=0; #define DEBUGGER_ON _no_db_=0 +#define DBUG_END() _db_end_ () #define DBUG_LOCK_FILE { _db_lock_file(); } #define DBUG_UNLOCK_FILE { _db_unlock_file(); } #define DBUG_OUTPUT(A) { _db_output_(A); } @@ -90,6 +92,7 @@ extern void _db_unlock_file(void); #define DBUG_IN_USE 0 #define DEBUGGER_OFF #define DEBUGGER_ON +#define DBUG_END() #define DBUG_LOCK_FILE #define DBUG_UNLOCK_FILE #define DBUG_OUTPUT(A) diff --git a/include/my_sys.h b/include/my_sys.h index 65a295ee39e765bf76975484777559074fac6cbf..229389f1ac50b4646db5a550c1b94055edad4446 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -75,6 +75,7 @@ extern int NEAR my_errno; /* Last error in mysys */ #define MY_CHECK_ERROR 1 /* Params to my_end; Check open-close */ #define MY_GIVE_INFO 2 /* Give time info about process*/ +#define MY_DONT_FREE_DBUG 4 /* Do not call DBUG_END() in my_end() */ #define ME_HIGHBYTE 8 /* Shift for colours */ #define ME_NOCUR 1 /* Don't use curses message */ diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 7713fd8dd4da91a42e7d2fa8a758c46040baaeef..c1e0703af101554a2491f0e2a812a3460fbcc0e0 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -178,7 +178,7 @@ void STDCALL mysql_server_end() /* If library called my_init(), free memory allocated by it */ if (!org_my_init_done) { - my_end(0); + my_end(MY_DONT_FREE_DBUG); #ifndef THREAD /* Remove TRACING, if enabled by mysql_debug() */ DBUG_POP(); diff --git a/mysys/my_init.c b/mysys/my_init.c index c2bfdde0ddd530e5739d0c45d5144b207aef6fd3..9b8d4db172f319491b8ec8858b37ad343ecdf7f6 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -196,8 +196,10 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", _CrtDumpMemoryLeaks(); #endif } + + if (!(infoflag & MY_DONT_FREE_DBUG)) + DBUG_END(); /* Must be done before my_thread_end */ #ifdef THREAD - DBUG_POP(); /* Must be done before my_thread_end */ my_thread_end(); my_thread_global_end(); #if defined(SAFE_MUTEX) diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ef2f52a33df3f12ff0926c6df09967a8a9337776..004b1761c77540c0630aaefe178a5936dae8aa7b 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -986,6 +986,10 @@ static void __cdecl kill_server(int sig_ptr) pthread_join(select_thread, NULL); // wait for main thread #endif /* __NETWARE__ */ +#if defined(__NETWARE__) || (defined(USE_ONE_SIGNAL_HAND) && !defined(__WIN__) && !defined(OS2)) + my_thread_end(); +#endif + pthread_exit(0); /* purecov: deadcode */ #endif /* EMBEDDED_LIBRARY */