From d3ee9abf2a15d96b6779b33ebe7606e7d53b8cd1 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Feb 2006 22:36:11 +0100 Subject: [PATCH 1/4] dbug changes: 1. dbug state is now local to a thread 2. new macros: DBUG_EXPLAIN, DBUG_EXPLAIN_INITIAL, DBUG_SET, DBUG_SET_INITIAL, DBUG_EVALUATE, DBUG_EVALUATE_IF 3. macros are do{}while(0) wrapped 4. incremental modifications to the dbug state (e.g. "+d,info:-t") 5. dbug code cleanup, style fixes 6. _db_on_ and DEBUGGER_ON/OFF removed 7. rest of MySQL code fixed because of 3 (missing ;) and 6 8. dbug manual updated 9. server variable @@debug (global and local) to control dbug from SQL! a. -#T to print timestamps in the log BitKeeper/deleted/.del-readme.prof~2f3bae1550a0038d: Delete: dbug/readme.prof client/mysqlslap.c: typo fixed configure.in: test for sleep() too dbug/dbug.c: thread local dbug settings DBUG_EXPLAIN,DBUG_EXPLAIN_INITIAL,DBUG_SET,DBUG_SET_INITIAL style changes to be more in line with MySQL code cleanup (many mallocs removed) incremental modification of dbug state (e.g. DBUG_PUSH("+t:-d,info")) DBUG_SET, _db_explain_ -#T dbug/monty.doc: obsolete and duplicate docs removed dbug/user.r: new features documented include/my_dbug.h: correct do{}while wrapping thread local dbug settings DBUG_EXPLAIN,DBUG_EXPLAIN_INITIAL,DBUG_SET,DBUG_SET_INITIAL DBUG_EVALUATE,DBUG_EVALUATE_IF libmysql/libmysql.c: remove _db_on_ and DEBUGGER_ON/OFF mysys/my_init.c: missed DBUG_RETURN mysys/my_thr_init.c: bugfix - transaction id's are unsigned mysys/testhash.c: remove _db_on_ and DEBUGGER_ON/OFF sql/ha_myisammrg.cc: missed ; sql/ha_ndbcluster.cc: remove _db_on_ and DEBUGGER_ON/OFF missed ; sql/ha_ndbcluster_binlog.cc: remove _db_on_ and DEBUGGER_ON/OFF missed ; sql/item_cmpfunc.cc: missed ; sql/lock.cc: missed DBUG_RETURN sql/log_event.cc: missed ; sql/mysqld.cc: remove _db_on_ and DEBUGGER_ON/OFF missed ; DBUG_SET_INITIAL sql/opt_range.cc: remove _db_on_ and DEBUGGER_ON/OFF sql/set_var.cc: class sys_var_thd_dbug and "debug" server variable sql/set_var.h: class sys_var_thd_dbug and "debug" server variable sql/slave.cc: missed ; sql/sql_cache.cc: missed ; sql/sql_plugin.cc: missed ; sql/sql_select.cc: remove _db_on_ and DEBUGGER_ON/OFF storage/heap/hp_test2.c: remove _db_on_ and DEBUGGER_ON/OFF storage/myisam/ft_eval.c: remove _db_on_ and DEBUGGER_ON/OFF storage/myisam/ft_test1.c: remove _db_on_ and DEBUGGER_ON/OFF storage/myisam/mi_open.c: remove _db_on_ and DEBUGGER_ON/OFF missed ; storage/myisam/mi_test1.c: remove _db_on_ and DEBUGGER_ON/OFF storage/myisam/mi_test2.c: remove _db_on_ and DEBUGGER_ON/OFF storage/myisam/mi_test3.c: remove _db_on_ and DEBUGGER_ON/OFF storage/ndb/src/ndbapi/DictCache.cpp: missed ; storage/ndb/src/ndbapi/NdbTransaction.cpp: missed ; tests/mysql_client_test.c: remove _db_on_ and DEBUGGER_ON/OFF --- client/mysqlslap.c | 4 +- configure.in | 2 +- dbug/dbug.c | 2726 +++++++++++---------- dbug/monty.doc | 13 +- dbug/readme.prof | 70 - dbug/user.r | 297 ++- include/my_dbug.h | 90 +- libmysql/libmysql.c | 6 - mysys/my_init.c | 1 + mysys/my_thr_init.c | 2 +- mysys/testhash.c | 2 - sql/ha_myisammrg.cc | 2 +- sql/ha_ndbcluster.cc | 17 +- sql/ha_ndbcluster_binlog.cc | 33 +- sql/item_cmpfunc.cc | 2 +- sql/lock.cc | 2 +- sql/log_event.cc | 2 +- sql/mysqld.cc | 20 +- sql/opt_range.cc | 8 +- sql/set_var.cc | 35 +- sql/set_var.h | 22 +- sql/slave.cc | 2 +- sql/sql_cache.cc | 6 +- sql/sql_plugin.cc | 6 +- sql/sql_select.cc | 4 +- storage/heap/hp_test2.c | 2 - storage/myisam/ft_eval.c | 1 - storage/myisam/ft_test1.c | 1 - storage/myisam/mi_open.c | 4 +- storage/myisam/mi_test1.c | 1 - storage/myisam/mi_test2.c | 2 - storage/myisam/mi_test3.c | 2 - storage/ndb/src/ndbapi/DictCache.cpp | 2 +- storage/ndb/src/ndbapi/NdbTransaction.cpp | 2 +- tests/mysql_client_test.c | 1 - 35 files changed, 1781 insertions(+), 1611 deletions(-) delete mode 100644 dbug/readme.prof diff --git a/client/mysqlslap.c b/client/mysqlslap.c index be034da0c8c..b80150a8d67 100644 --- a/client/mysqlslap.c +++ b/client/mysqlslap.c @@ -730,10 +730,10 @@ build_query_string(void) strmov(ptr->string, query_string.str); DBUG_PRINT("info", ("user_supplied_query %s", ptr->string)); dynstr_free(&query_string); - DBUG_RETURN(0); + DBUG_RETURN(ptr); } -static int +static int get_options(int *argc,char ***argv) { int ho_error; diff --git a/configure.in b/configure.in index bdaa1f5166e..21a51d86a23 100644 --- a/configure.in +++ b/configure.in @@ -1856,7 +1856,7 @@ AC_CHECK_FUNCS(alarm bcmp bfill bmove bsearch bzero \ pthread_setprio_np pthread_setschedparam pthread_sigmask readlink \ realpath rename rint rwlock_init setupterm \ shmget shmat shmdt shmctl sigaction sigemptyset sigaddset \ - sighold sigset sigthreadmask \ + sighold sigset sigthreadmask sleep \ snprintf socket stpcpy strcasecmp strerror strsignal strnlen strpbrk strstr strtol \ strtoll strtoul strtoull tell tempnam thr_setconcurrency vidattr \ posix_fallocate) diff --git a/dbug/dbug.c b/dbug/dbug.c index 91b7e7b6c4c..e6323de1051 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -1,69 +1,73 @@ /****************************************************************************** - * * - * N O T I C E * - * * - * Copyright Abandoned, 1987, Fred Fish * - * * - * * - * This previously copyrighted work has been placed into the public * - * domain by the author and may be freely used for any purpose, * - * private or commercial. * - * * - * Because of the number of inquiries I was receiving about the use * - * of this product in commercially developed works I have decided to * - * simply make it public domain to further its unrestricted use. I * - * specifically would be most happy to see this material become a * - * part of the standard Unix distributions by AT&T and the Berkeley * - * Computer Science Research Group, and a standard part of the GNU * - * system from the Free Software Foundation. * - * * - * I would appreciate it, as a courtesy, if this notice is left in * - * all copies and derivative works. Thank you. * - * * - * The author makes no warranty of any kind with respect to this * + * * + * N O T I C E * + * * + * Copyright Abandoned, 1987, Fred Fish * + * * + * * + * This previously copyrighted work has been placed into the public * + * domain by the author and may be freely used for any purpose, * + * private or commercial. * + * * + * Because of the number of inquiries I was receiving about the use * + * of this product in commercially developed works I have decided to * + * simply make it public domain to further its unrestricted use. I * + * specifically would be most happy to see this material become a * + * part of the standard Unix distributions by AT&T and the Berkeley * + * Computer Science Research Group, and a standard part of the GNU * + * system from the Free Software Foundation. * + * * + * I would appreciate it, as a courtesy, if this notice is left in * + * all copies and derivative works. Thank you. * + * * + * The author makes no warranty of any kind with respect to this * * product and explicitly disclaims any implied warranties of mer- * - * chantability or fitness for any particular purpose. * - * * + * chantability or fitness for any particular purpose. * + * * ****************************************************************************** */ - /* * FILE * - * dbug.c runtime support routines for dbug package + * dbug.c runtime support routines for dbug package * * SCCS * - * @(#)dbug.c 1.25 7/25/89 + * @(#)dbug.c 1.25 7/25/89 * * DESCRIPTION * - * These are the runtime support routines for the dbug package. - * The dbug package has two main components; the user include - * file containing various macro definitions, and the runtime - * support routines which are called from the macro expansions. + * These are the runtime support routines for the dbug package. + * The dbug package has two main components; the user include + * file containing various macro definitions, and the runtime + * support routines which are called from the macro expansions. * - * Externally visible functions in the runtime support module - * use the naming convention pattern "_db_xx...xx_", thus - * they are unlikely to collide with user defined function names. + * Externally visible functions in the runtime support module + * use the naming convention pattern "_db_xx...xx_", thus + * they are unlikely to collide with user defined function names. * * AUTHOR(S) * - * Fred Fish (base code) - * Enhanced Software Technologies, Tempe, AZ - * asuvax!mcdphx!estinc!fnf + * Fred Fish (base code) + * Enhanced Software Technologies, Tempe, AZ + * asuvax!mcdphx!estinc!fnf * - * Binayak Banerjee (profiling enhancements) - * seismo!bpa!sjuvax!bbanerje + * Binayak Banerjee (profiling enhancements) + * seismo!bpa!sjuvax!bbanerje * - * Michael Widenius: - * DBUG_DUMP - To dump a block of memory. + * Michael Widenius: + * DBUG_DUMP - To dump a block of memory. * PUSH_FLAG "O" - To be used insted of "o" if we * want flushing after each write - * PUSH_FLAG "A" - as 'O', but we will append to the out file instead - * of creating a new one. - * Check of malloc on entry/exit (option "S") + * PUSH_FLAG "A" - as 'O', but we will append to the out file instead + * of creating a new one. + * Check of malloc on entry/exit (option "S") + * + * DBUG_EXECUTE_IF + * incremental mode (-#+t:-d,info ...) + * DBUG_SET, _db_explain_ + * */ #ifdef DBUG_OFF @@ -76,51 +80,40 @@ #include #endif -#ifdef _DBUG_CONDITION_ -#define _DBUG_START_CONDITION_ "d:t" -#else -#define _DBUG_START_CONDITION_ "" -#endif - /* - * Manifest constants that should not require any changes. + * Manifest constants which may be "tuned" if desired. */ -#define EOS '\000' /* End Of String marker */ +#define PRINTBUF 1024 /* Print buffer size */ +#define INDENT 2 /* Indentation per trace level */ +#define MAXDEPTH 200 /* Maximum trace depth default */ /* - * Manifest constants which may be "tuned" if desired. + * The following flags are used to determine which + * capabilities the user has enabled with the settings + * push macro. */ -#define PRINTBUF 1024 /* Print buffer size */ -#define INDENT 2 /* Indentation per trace level */ -#define MAXDEPTH 200 /* Maximum trace depth default */ +#define TRACE_ON 000001 /* Trace enabled */ +#define DEBUG_ON 000002 /* Debug enabled */ +#define FILE_ON 000004 /* File name print enabled */ +#define LINE_ON 000010 /* Line number print enabled */ +#define DEPTH_ON 000020 /* Function nest level print enabled */ +#define PROCESS_ON 000040 /* Process name print enabled */ +#define NUMBER_ON 000100 /* Number each line of output */ +#define PROFILE_ON 000200 /* Print out profiling code */ +#define PID_ON 000400 /* Identify each line with process id */ +#define TIMESTAMP_ON 001000 /* timestamp every line of output */ +#define SANITY_CHECK_ON 002000 /* Check safemalloc on DBUG_ENTER */ +#define FLUSH_ON_WRITE 004000 /* Flush on every write */ +#define OPEN_APPEND 010000 /* Open for append */ + +#define TRACING (cs->stack->flags & TRACE_ON) +#define DEBUGGING (cs->stack->flags & DEBUG_ON) +#define PROFILING (cs->stack->flags & PROFILE_ON) /* - * The following flags are used to determine which - * capabilities the user has enabled with the state - * push macro. - */ - -#define TRACE_ON 000001 /* Trace enabled */ -#define DEBUG_ON 000002 /* Debug enabled */ -#define FILE_ON 000004 /* File name print enabled */ -#define LINE_ON 000010 /* Line number print enabled */ -#define DEPTH_ON 000020 /* Function nest level print enabled */ -#define PROCESS_ON 000040 /* Process name print enabled */ -#define NUMBER_ON 000100 /* Number each line of output */ -#define PROFILE_ON 000200 /* Print out profiling code */ -#define PID_ON 000400 /* Identify each line with process id */ -#define SANITY_CHECK_ON 001000 /* Check safemalloc on DBUG_ENTER */ -#define FLUSH_ON_WRITE 002000 /* Flush on every write */ - -#define TRACING (stack -> flags & TRACE_ON) -#define DEBUGGING (stack -> flags & DEBUG_ON) -#define PROFILING (stack -> flags & PROFILE_ON) -#define STREQ(a,b) (strcmp(a,b) == 0) - -/* - * Typedefs to make things more obvious. + * Typedefs to make things more obvious. */ #ifndef __WIN__ @@ -130,13 +123,13 @@ typedef int BOOLEAN; #endif /* - * Make it easy to change storage classes if necessary. + * Make it easy to change storage classes if necessary. */ -#define IMPORT extern /* Names defined externally */ -#define EXPORT /* Allocated here, available globally */ -#define AUTO auto /* Names to be allocated on stack */ -#define REGISTER register /* Names to be placed in registers */ +#define IMPORT extern /* Names defined externally */ +#define EXPORT /* Allocated here, available globally */ +#define AUTO auto /* Names to be allocated on stack */ +#define REGISTER register /* Names to be placed in registers */ /* * The default file for profiling. Could also add another flag @@ -151,151 +144,148 @@ typedef int BOOLEAN; * */ -#define PROF_FILE "dbugmon.out" -#define PROF_EFMT "E\t%ld\t%s\n" -#define PROF_SFMT "S\t%lx\t%lx\t%s\n" -#define PROF_XFMT "X\t%ld\t%s\n" +#define PROF_FILE "dbugmon.out" +#define PROF_EFMT "E\t%ld\t%s\n" +#define PROF_SFMT "S\t%lx\t%lx\t%s\n" +#define PROF_XFMT "X\t%ld\t%s\n" -#ifdef M_I386 /* predefined by xenix 386 compiler */ +#ifdef M_I386 /* predefined by xenix 386 compiler */ #define AUTOS_REVERSE 1 #endif /* - * Variables which are available externally but should only - * be accessed via the macro package facilities. - */ - -EXPORT FILE *_db_fp_ = (FILE *) 0; /* Output stream, default stderr */ -EXPORT char *_db_process_ = (char*) "dbug"; /* Pointer to process name; argv[0] */ -EXPORT FILE *_db_pfp_ = (FILE *)0; /* Profile stream, 'dbugmon.out' */ -EXPORT BOOLEAN _db_on_ = FALSE; /* TRUE if debugging currently on */ -EXPORT BOOLEAN _db_pon_ = FALSE; /* TRUE if profile currently on */ -EXPORT BOOLEAN _no_db_ = FALSE; /* TRUE if no debugging at all */ - -/* - * Externally supplied functions. + * Externally supplied functions. */ #ifndef HAVE_PERROR -static void perror (); /* Fake system/library error print routine */ +static void perror(); /* Fake system/library error print routine */ #endif -IMPORT int _sanity(const char *file,uint line); +IMPORT int _sanity(const char *file,uint line); /* safemalloc sanity checker */ /* - * The user may specify a list of functions to trace or - * debug. These lists are kept in a linear linked list, - * a very simple implementation. + * The user may specify a list of functions to trace or + * debug. These lists are kept in a linear linked list, + * a very simple implementation. */ struct link { - char *str; /* Pointer to link's contents */ struct link *next_link; /* Pointer to the next link */ + char str[1]; /* Pointer to link's contents */ }; /* - * Debugging states can be pushed or popped off of a - * stack which is implemented as a linked list. Note - * that the head of the list is the current state and the - * stack is pushed by adding a new state to the head of the - * list or popped by removing the first link. - */ - -struct state { - int flags; /* Current state flags */ - int maxdepth; /* Current maximum trace depth */ - uint delay; /* Delay after each output line */ - int sub_level; /* Sub this from code_state->level */ - FILE *out_file; /* Current output stream */ - FILE *prof_file; /* Current profiling stream */ - char name[FN_REFLEN]; /* Name of output file */ - struct link *functions; /* List of functions */ - struct link *p_functions; /* List of profiled functions */ - struct link *keywords; /* List of debug keywords */ - struct link *processes; /* List of process names */ - struct state *next_state; /* Next state in the list */ -}; - - -/* - * Local variables not seen by user. - */ - - -static my_bool init_done = FALSE; /* Set to TRUE when initialization done */ -static struct state *stack=0; - -typedef struct st_code_state { - const char *func; /* Name of current user function */ - const char *file; /* Name of current user file */ - char **framep; /* Pointer to current frame */ - const char *jmpfunc; /* Remember current function for setjmp */ - const char *jmpfile; /* Remember current file for setjmp */ - int lineno; /* Current debugger output line number */ - int level; /* Current function nesting level */ - int disable_output; /* Set to it if output is disabled */ - int jmplevel; /* Remember nesting level at setjmp () */ - -/* - * The following variables are used to hold the state information - * between the call to _db_pargs_() and _db_doprnt_(), during - * expansion of the DBUG_PRINT macro. This is the only macro - * that currently uses these variables. + * Debugging settings can be pushed or popped off of a + * stack which is implemented as a linked list. Note + * that the head of the list is the current settings and the + * stack is pushed by adding a new settings to the head of the + * list or popped by removing the first link. * - * These variables are currently used only by _db_pargs_() and - * _db_doprnt_(). + * Note: if out_file is NULL, the other fields are not initialized at all! */ - uint u_line; /* User source code line number */ - int locked; /* If locked with _db_lock_file */ - const char *u_keyword; /* Keyword for current macro */ +struct settings { + int flags; /* Current settings flags */ + int maxdepth; /* Current maximum trace depth */ + uint delay; /* Delay after each output line */ + int sub_level; /* Sub this from code_state->level */ + FILE *out_file; /* Current output stream */ + FILE *prof_file; /* Current profiling stream */ + char name[FN_REFLEN]; /* Name of output file */ + struct link *functions; /* List of functions */ + struct link *p_functions; /* List of profiled functions */ + struct link *keywords; /* List of debug keywords */ + struct link *processes; /* List of process names */ + struct settings *next; /* Next settings in the list */ +}; + +#define is_shared(S, V) ((S)->next && (S)->next->V == (S)->V) + +/* + * Local variables not seen by user. + */ + + +static BOOLEAN init_done= FALSE; /* Set to TRUE when initialization done */ +static struct settings init_settings; +static char *db_process= 0; /* Pointer to process name; argv[0] */ + +typedef struct _db_code_state_ { + const char *process; /* Pointer to process name; usually argv[0] */ + const char *func; /* Name of current user function */ + const char *file; /* Name of current user file */ + char **framep; /* Pointer to current frame */ + struct settings *stack; /* debugging settings */ + const char *jmpfunc; /* Remember current function for setjmp */ + const char *jmpfile; /* Remember current file for setjmp */ + int lineno; /* Current debugger output line number */ + int level; /* Current function nesting level */ + int jmplevel; /* Remember nesting level at setjmp() */ + +/* + * The following variables are used to hold the state information + * between the call to _db_pargs_() and _db_doprnt_(), during + * expansion of the DBUG_PRINT macro. This is the only macro + * that currently uses these variables. + * + * These variables are currently used only by _db_pargs_() and + * _db_doprnt_(). + */ + + uint u_line; /* User source code line number */ + int locked; /* If locked with _db_lock_file_ */ + const char *u_keyword; /* Keyword for current macro */ } CODE_STATE; - /* Parse a debug command string */ -static struct link *ListParse(char *ctlp); - /* Make a fresh copy of a string */ -static char *StrDup(const char *str); - /* Open debug output stream */ -static void DBUGOpenFile(const char *name, int append); -#ifndef THREAD - /* Open profile output stream */ -static FILE *OpenProfile(const char *name); - /* Profile if asked for it */ -static BOOLEAN DoProfile(void); -#endif - /* Return current user time (ms) */ -#ifndef THREAD -static unsigned long Clock (void); -#endif - /* Close debug output stream */ -static void CloseFile(FILE *fp); - /* Push current debug state */ -static void PushState(void); - /* Test for tracing enabled */ -static BOOLEAN DoTrace(CODE_STATE *state); - /* Test to see if file is writable */ +/* + The test below is so we could call functions with DBUG_ENTER before + my_thread_init(). +*/ +#define get_code_state_or_return if (!cs && !((cs=code_state()))) return + + /* Handling lists */ +static struct link *ListAdd(struct link *, const char *, const char *); +static struct link *ListDel(struct link *, const char *, const char *); +static struct link *ListCopy(struct link *); +static void FreeList(struct link *linkp); + + /* OpenClose debug output stream */ +static void DBUGOpenFile(CODE_STATE *,const char *, const char *, int); +static void DBUGCloseFile(CODE_STATE *cs, FILE *fp); + /* Push current debug settings */ +static void PushState(CODE_STATE *cs); + /* Test for tracing enabled */ +static BOOLEAN DoTrace(CODE_STATE *cs); + + /* Test to see if file is writable */ #if !(!defined(HAVE_ACCESS) || defined(MSDOS)) static BOOLEAN Writable(char *pathname); - /* Change file owner and group */ -static void ChangeOwner(char *pathname); - /* Allocate memory for runtime support */ + /* Change file owner and group */ +static void ChangeOwner(CODE_STATE *cs, char *pathname); + /* Allocate memory for runtime support */ #endif + +static void DoPrefix(CODE_STATE *cs, uint line); + static char *DbugMalloc(size_t size); - /* Remove leading pathname components */ -static char *BaseName(const char *pathname); -static void DoPrefix(uint line); -static void FreeList(struct link *linkp); -static void Indent(int indent); +static const char *BaseName(const char *pathname); +static void Indent(CODE_STATE *cs, int indent); static BOOLEAN InList(struct link *linkp,const char *cp); static void dbug_flush(CODE_STATE *); static void DbugExit(const char *why); -static int DelayArg(int value); - /* Supplied in Sys V runtime environ */ - /* Break string into tokens */ -static char *static_strtok(char *s1,pchar chr); +static const char *DbugStrTok(const char *s); + +#ifndef THREAD + /* Open profile output stream */ +static FILE *OpenProfile(CODE_STATE *cs, const char *name); + /* Profile if asked for it */ +static BOOLEAN DoProfile(CODE_STATE *); + /* Return current user time (ms) */ +static unsigned long Clock(void); +#endif /* - * Miscellaneous printf format strings. + * Miscellaneous printf format strings. */ #define ERR_MISSING_RETURN "%s: missing DBUG_RETURN or DBUG_VOID_RETURN macro in function \"%s\"\n" @@ -305,34 +295,21 @@ static char *static_strtok(char *s1,pchar chr); #define ERR_CHOWN "%s: can't change owner/group of \"%s\": " /* - * Macros and defines for testing file accessibility under UNIX and MSDOS. + * Macros and defines for testing file accessibility under UNIX and MSDOS. */ #undef EXISTS #if !defined(HAVE_ACCESS) || defined(MSDOS) -#define EXISTS(pathname) (FALSE) /* Assume no existance */ +#define EXISTS(pathname) (FALSE) /* Assume no existance */ #define Writable(name) (TRUE) #else -#define EXISTS(pathname) (access (pathname, F_OK) == 0) -#define WRITABLE(pathname) (access (pathname, W_OK) == 0) +#define EXISTS(pathname) (access(pathname, F_OK) == 0) +#define WRITABLE(pathname) (access(pathname, W_OK) == 0) #endif #ifndef MSDOS -#define ChangeOwner(name) +#define ChangeOwner(cs,name) #endif -/* - * Translate some calls among different systems. - */ - -#if defined(unix) || defined(xenix) || defined(VMS) || defined(__NetBSD__) -# define Delay(A) sleep((uint) A) -#elif defined(AMIGA) -IMPORT int Delay (); /* Pause for given number of ticks */ -#else -static int Delay(int ticks); -#endif - - /* ** Macros to allow dbugging with threads */ @@ -341,593 +318,827 @@ static int Delay(int ticks); #include pthread_mutex_t THR_LOCK_dbug; -static void init_dbug_state(void) -{ - pthread_mutex_init(&THR_LOCK_dbug,MY_MUTEX_INIT_FAST); -} - static CODE_STATE *code_state(void) { - CODE_STATE *state=0; - struct st_my_thread_var *tmp=my_thread_var; - if (tmp) + CODE_STATE *cs=0; + struct st_my_thread_var *tmp; + + if (!init_done) { - if (!(state=(CODE_STATE *) tmp->dbug)) + pthread_mutex_init(&THR_LOCK_dbug,MY_MUTEX_INIT_FAST); + bzero(&init_settings, sizeof(init_settings)); + init_settings.out_file=stderr; + init_settings.flags=OPEN_APPEND; + init_done=TRUE; + } + + if ((tmp=my_thread_var)) + { + if (!(cs=(CODE_STATE *) tmp->dbug)) { - state=(CODE_STATE*) DbugMalloc(sizeof(*state)); - bzero((char*) state,sizeof(*state)); - state->func="?func"; - state->file="?file"; - tmp->dbug=(gptr) state; + cs=(CODE_STATE*) DbugMalloc(sizeof(*cs)); + bzero((char*) cs,sizeof(*cs)); + cs->process= db_process ? db_process : "dbug"; + cs->func="?func"; + cs->file="?file"; + cs->stack=&init_settings; + tmp->dbug=(gptr) cs; } } - return state; + return cs; } #else /* !THREAD */ -#define init_dbug_state() -#define code_state() (&static_code_state) -#define pthread_mutex_lock(A) {} -#define pthread_mutex_unlock(A) {} static CODE_STATE static_code_state= { - "?func", "?file", NULL, NullS, NullS, 0,0,0,0,0,0, NullS + "dbug", "?func", "?file", NULL, &init_settings, + NullS, NullS, 0,0,0,0,0,NullS }; + +static CODE_STATE *code_state(void) +{ + if (!init_done) + { + bzero(&init_settings, sizeof(init_settings)); + init_settings.out_file=stderr; + init_settings.flags=OPEN_APPEND; + init_done=TRUE; + } + return &static_code_state; +} + +#define pthread_mutex_lock(A) {} +#define pthread_mutex_unlock(A) {} #endif +/* + * Translate some calls among different systems. + */ + +#ifdef HAVE_SLEEP +/* sleep() wants seconds */ +#define Delay(A) sleep(((uint) A)/10) +#else +#define Delay(A) (0) +#endif + +/* + * FUNCTION + * + * _db_process_ give the name to the current process/thread + * + * SYNOPSIS + * + * VOID _db_push_(name) + * char *name; + * + */ + +void _db_process_(const char *name) +{ + CODE_STATE *cs=0; + + if (!db_process) + db_process= name; + + get_code_state_or_return; + cs->process= name; +} + /* * FUNCTION * - * _db_push_ push current debugger state and set up new one + * _db_push_ push current debugger settings and set up new one * * SYNOPSIS * - * VOID _db_push_ (control) - * char *control; + * VOID _db_push_(control) + * char *control; * * DESCRIPTION * - * Given pointer to a debug control string in "control", pushes - * the current debug state, parses the control string, and sets - * up a new debug state. - * - * The only attribute of the new state inherited from the previous - * state is the current function nesting level. This can be - * overridden by using the "r" flag in the control string. - * - * The debug control string is a sequence of colon separated fields - * as follows: - * - * ::...: - * - * Each field consists of a mandatory flag character followed by - * an optional "," and comma separated list of modifiers: - * - * flag[,modifier,modifier,...,modifier] - * - * The currently recognized flag characters are: - * - * d Enable output from DBUG_ macros for - * for the current state. May be followed - * by a list of keywords which selects output - * only for the DBUG macros with that keyword. - * A null list of keywords implies output for - * all macros. - * - * D Delay after each debugger output line. - * The argument is the number of tenths of seconds - * to delay, subject to machine capabilities. - * I.E. -#D,20 is delay two seconds. - * - * f Limit debugging and/or tracing, and profiling to the - * list of named functions. Note that a null list will - * disable all functions. The appropriate "d" or "t" - * flags must still be given, this flag only limits their - * actions if they are enabled. - * - * F Identify the source file name for each - * line of debug or trace output. - * - * i Identify the process with the pid for each line of - * debug or trace output. - * - * g Enable profiling. Create a file called 'dbugmon.out' - * containing information that can be used to profile - * the program. May be followed by a list of keywords - * that select profiling only for the functions in that - * list. A null list implies that all functions are - * considered. - * - * L Identify the source file line number for - * each line of debug or trace output. - * - * n Print the current function nesting depth for - * each line of debug or trace output. - * - * N Number each line of dbug output. - * - * o Redirect the debugger output stream to the - * specified file. The default output is stderr. - * - * O As O but the file is really flushed between each - * write. When neaded the file is closed and reopened - * between each write. - * - * p Limit debugger actions to specified processes. - * A process must be identified with the - * DBUG_PROCESS macro and match one in the list - * for debugger actions to occur. - * - * P Print the current process name for each - * line of debug or trace output. - * - * r When pushing a new state, do not inherit - * the previous state's function nesting level. - * Useful when the output is to start at the - * left margin. - * - * S Do function _sanity(_file_,_line_) at each - * debugged function until _sanity() returns - * something that differs from 0. - * (Moustly used with safemalloc) - * - * t Enable function call/exit trace lines. - * May be followed by a list (containing only - * one modifier) giving a numeric maximum - * trace level, beyond which no output will - * occur for either debugging or tracing - * macros. The default is a compile time - * option. - * - * Some examples of debug control strings which might appear - * on a shell command line (the "-#" is typically used to - * introduce a control string to an application program) are: - * - * -#d:t - * -#d:f,main,subr1:F:L:t,20 - * -#d,input,output,files:n - * - * For convenience, any leading "-#" is stripped off. + * Given pointer to a debug control string in "control", pushes + * the current debug settings, parses the control string, and sets + * up a new debug settings with _db_set_() * */ -void _db_push_ (const char *control) +void _db_push_(const char *control) { - reg1 char *scan; - reg2 struct link *temp; - CODE_STATE *state; - char *new_str; + CODE_STATE *cs=0; + get_code_state_or_return; + PushState(cs); + _db_set_(cs, control); - if (! _db_fp_) - _db_fp_= stderr; /* Output stream, default stderr */ +} - if (*control == '-') +/* + * FUNCTION + * + * _db_set_init_ set initial debugger settings + * + * SYNOPSIS + * + * VOID _db_set_init_(control) + * char *control; + * + * DESCRIPTION + * see _db_set_ + * + */ + +void _db_set_init_(const char *control) +{ + CODE_STATE cs; + bzero((char*) &cs,sizeof(cs)); + cs.stack=&init_settings; + _db_set_(&cs, control); +} + +/* + * FUNCTION + * + * _db_set_ set current debugger settings + * + * SYNOPSIS + * + * VOID _db_set_(control) + * char *control; + * + * DESCRIPTION + * + * Given pointer to a debug control string in "control", + * parses the control string, and sets + * up a current debug settings. + * + * The debug control string is a sequence of colon separated fields + * as follows: + * + * [+]::...: + * + * Each field consists of a mandatory flag character followed by + * an optional "," and comma separated list of modifiers: + * + * [sign]flag[,modifier,modifier,...,modifier] + * + * See the manual for the list of supported signs, flags, and modifiers + * + * For convenience, any leading "-#" is stripped off. + * + */ + +void _db_set_(CODE_STATE *cs, const char *control) +{ + const char *end; + int rel=0; + + get_code_state_or_return; + + if (control[0] == '-' && control[1] == '#') + control+=2; + + rel= control[0] == '+' || control[0] == '-'; + if (!rel || (!cs->stack->out_file && !cs->stack->next)) { - if (*++control == '#') - control++; + cs->stack->flags= 0; + cs->stack->delay= 0; + cs->stack->maxdepth= 0; + cs->stack->sub_level= 0; + cs->stack->out_file= stderr; + cs->stack->prof_file= NULL; + cs->stack->functions= NULL; + cs->stack->p_functions= NULL; + cs->stack->keywords= NULL; + cs->stack->processes= NULL; + } + else if (!cs->stack->out_file) + { + cs->stack->flags= cs->stack->next->flags; + cs->stack->delay= cs->stack->next->delay; + cs->stack->maxdepth= cs->stack->next->maxdepth; + cs->stack->sub_level= cs->stack->next->sub_level; + strcpy(cs->stack->name, cs->stack->next->name); + cs->stack->out_file= cs->stack->next->out_file; + cs->stack->prof_file= cs->stack->next->prof_file; + if (cs->stack->next == &init_settings) + { + /* never share with the global parent - it can change under your feet */ + cs->stack->functions= ListCopy(init_settings.functions); + cs->stack->p_functions= ListCopy(init_settings.p_functions); + cs->stack->keywords= ListCopy(init_settings.keywords); + cs->stack->processes= ListCopy(init_settings.processes); + } + else + { + cs->stack->functions= cs->stack->next->functions; + cs->stack->p_functions= cs->stack->next->p_functions; + cs->stack->keywords= cs->stack->next->keywords; + cs->stack->processes= cs->stack->next->processes; + } } - if (*control) - _no_db_=0; /* We are using dbug after all */ - new_str = StrDup (control); - PushState (); - state=code_state(); - - scan = static_strtok (new_str, ':'); - for (; scan != NULL; scan = static_strtok ((char *)NULL, ':')) { - switch (*scan++) { + end= DbugStrTok(control); + while (1) + { + int c, sign= (*control == '+') ? 1 : (*control == '-') ? -1 : 0; + if (sign) control++; + if (!rel) sign=0; + c= *control++; + if (*control == ',') control++; + switch (c) { case 'd': - _db_on_ = TRUE; - stack -> flags |= DEBUG_ON; - if (*scan++ == ',') { - stack -> keywords = ListParse (scan); + if (sign < 0 && control == end) + { + if (!is_shared(cs->stack, keywords)) + FreeList(cs->stack->keywords); + cs->stack->keywords=NULL; + cs->stack->flags &= ~DEBUG_ON; + break; } + if (rel && is_shared(cs->stack, keywords)) + cs->stack->keywords= ListCopy(cs->stack->keywords); + if (sign < 0) + { + if (DEBUGGING) + cs->stack->keywords= ListDel(cs->stack->keywords, control, end); + break; + } + cs->stack->keywords= ListAdd(cs->stack->keywords, control, end); + cs->stack->flags |= DEBUG_ON; break; case 'D': - stack -> delay = 0; - if (*scan++ == ',') { - temp = ListParse (scan); - stack -> delay = DelayArg (atoi (temp -> str)); - FreeList (temp); - } + cs->stack->delay= atoi(control); break; case 'f': - if (*scan++ == ',') { - stack -> functions = ListParse (scan); + if (sign < 0 && control == end) + { + if (!is_shared(cs->stack,functions)) + FreeList(cs->stack->functions); + cs->stack->functions=NULL; + break; } + if (rel && is_shared(cs->stack,functions)) + cs->stack->functions= ListCopy(cs->stack->functions); + if (sign < 0) + cs->stack->functions= ListDel(cs->stack->functions, control, end); + else + cs->stack->functions= ListAdd(cs->stack->functions, control, end); break; case 'F': - stack -> flags |= FILE_ON; + if (sign < 0) + cs->stack->flags &= ~FILE_ON; + else + cs->stack->flags |= FILE_ON; break; case 'i': - stack -> flags |= PID_ON; + if (sign < 0) + cs->stack->flags &= ~PID_ON; + else + cs->stack->flags |= PID_ON; break; #ifndef THREAD case 'g': - _db_pon_ = TRUE; - if (OpenProfile(PROF_FILE)) + if (OpenProfile(cs, PROF_FILE)) { - stack -> flags |= PROFILE_ON; - if (*scan++ == ',') - stack -> p_functions = ListParse (scan); + cs->stack->flags |= PROFILE_ON; + cs->stack->p_functions= ListAdd(cs->stack->p_functions, control, end); } break; #endif case 'L': - stack -> flags |= LINE_ON; + if (sign < 0) + cs->stack->flags &= ~LINE_ON; + else + cs->stack->flags |= LINE_ON; break; case 'n': - stack -> flags |= DEPTH_ON; + if (sign < 0) + cs->stack->flags &= ~DEPTH_ON; + else + cs->stack->flags |= DEPTH_ON; break; case 'N': - stack -> flags |= NUMBER_ON; + if (sign < 0) + cs->stack->flags &= ~NUMBER_ON; + else + cs->stack->flags |= NUMBER_ON; break; case 'A': case 'O': - stack -> flags |= FLUSH_ON_WRITE; + cs->stack->flags |= FLUSH_ON_WRITE; + /* fall through */ case 'a': case 'o': - if (*scan++ == ',') { - temp = ListParse (scan); - DBUGOpenFile(temp -> str, (int) (scan[-2] == 'A' || scan[-2] == 'a')); - FreeList (temp); - } else { - DBUGOpenFile ("-",0); + if (sign < 0) + { + if (!is_shared(cs->stack, out_file)) + DBUGCloseFile(cs, cs->stack->out_file); + cs->stack->flags &= ~FLUSH_ON_WRITE; + cs->stack->out_file= stderr; + break; } + if (c == 'a' || c == 'A') + cs->stack->flags |= OPEN_APPEND; + else + cs->stack->flags &= ~OPEN_APPEND; + if (control != end) + DBUGOpenFile(cs, control, end, cs->stack->flags & OPEN_APPEND); + else + DBUGOpenFile(cs, "-",0,0); break; case 'p': - if (*scan++ == ',') { - stack -> processes = ListParse (scan); + if (sign < 0 && control == end) + { + if (!is_shared(cs->stack,processes)) + FreeList(cs->stack->processes); + cs->stack->processes=NULL; + break; } + if (rel && is_shared(cs->stack, processes)) + cs->stack->processes= ListCopy(cs->stack->processes); + if (sign < 0) + cs->stack->processes= ListDel(cs->stack->processes, control, end); + else + cs->stack->processes= ListAdd(cs->stack->processes, control, end); break; case 'P': - stack -> flags |= PROCESS_ON; + if (sign < 0) + cs->stack->flags &= ~PROCESS_ON; + else + cs->stack->flags |= PROCESS_ON; break; case 'r': - stack->sub_level= state->level; + cs->stack->sub_level= cs->level; break; case 't': - stack -> flags |= TRACE_ON; - if (*scan++ == ',') { - temp = ListParse (scan); - stack -> maxdepth = atoi (temp -> str); - FreeList (temp); + if (sign < 0) + { + if (control != end) + cs->stack->maxdepth-= atoi(control); + else + cs->stack->maxdepth= 0; } + else + { + if (control != end) + cs->stack->maxdepth+= atoi(control); + else + cs->stack->maxdepth= MAXDEPTH; + } + if (cs->stack->maxdepth > 0) + cs->stack->flags |= TRACE_ON; + else + cs->stack->flags &= ~TRACE_ON; + break; + case 'T': + if (sign < 0) + cs->stack->flags &= ~TIMESTAMP_ON; + else + cs->stack->flags |= TIMESTAMP_ON; break; case 'S': - stack -> flags |= SANITY_CHECK_ON; + if (sign < 0) + cs->stack->flags &= ~SANITY_CHECK_ON; + else + cs->stack->flags |= SANITY_CHECK_ON; break; } + if (!*end) + break; + control=end+1; + end= DbugStrTok(control); } - free (new_str); } - /* * FUNCTION * - * _db_pop_ pop the debug stack + * _db_pop_ pop the debug stack * * DESCRIPTION * - * Pops the debug stack, returning the debug state to its - * condition prior to the most recent _db_push_ invocation. - * Note that the pop will fail if it would remove the last - * valid state from the stack. This prevents user errors - * in the push/pop sequence from screwing up the debugger. - * Maybe there should be some kind of warning printed if the - * user tries to pop too many states. + * Pops the debug stack, returning the debug settings to its + * condition prior to the most recent _db_push_ invocation. + * Note that the pop will fail if it would remove the last + * valid settings from the stack. This prevents user errors + * in the push/pop sequence from screwing up the debugger. + * Maybe there should be some kind of warning printed if the + * user tries to pop too many states. * */ -void _db_pop_ () +void _db_pop_() { - reg1 struct state *discard; - discard = stack; - if (discard != NULL && discard -> next_state != NULL) { - stack = discard -> next_state; - _db_fp_ = stack -> out_file; - _db_pfp_ = stack -> prof_file; - if (discard -> keywords != NULL) { - FreeList (discard -> keywords); + struct settings *discard; + CODE_STATE *cs=0; + + get_code_state_or_return; + + discard= cs->stack; + if (discard->next != NULL) + { + cs->stack= discard->next; + if (!is_shared(discard, keywords)) + FreeList(discard->keywords); + if (!is_shared(discard, functions)) + FreeList(discard->functions); + if (!is_shared(discard, processes)) + FreeList(discard->processes); + if (!is_shared(discard, p_functions)) + FreeList(discard->p_functions); + if (!is_shared(discard, out_file)) + DBUGCloseFile(cs, discard->out_file); + if (discard->prof_file) + DBUGCloseFile(cs, discard->prof_file); + free((char *) discard); + } +} + +/* + * FUNCTION + * + * _db_explain_ generates 'control' string for the current settings + * + * RETURN + * 0 - ok + * 1 - buffer too short, output truncated + * + */ + +/* helper macros */ +#define char_to_buf(C) do { \ + *buf++=(C); \ + if (buf >= end) goto overflow; \ + } while (0) +#define str_to_buf(S) do { \ + char_to_buf(','); \ + buf=strnmov(buf, (S), len+1); \ + if (buf >= end) goto overflow; \ + } while (0) +#define list_to_buf(l) do { \ + struct link *listp=(l); \ + while (listp) \ + { \ + str_to_buf(listp->str); \ + listp=listp->next_link; \ + } \ + } while (0) +#define int_to_buf(i) do { \ + char b[50]; \ + int10_to_str((i), b, 10); \ + str_to_buf(b); \ + } while (0) +#define colon_to_buf do { \ + if (buf != start) char_to_buf(':'); \ + } while(0) +#define op_int_to_buf(C, val, def) do { \ + if ((val) != (def)) \ + { \ + colon_to_buf; \ + char_to_buf((C)); \ + int_to_buf(val); \ + } \ + } while (0) +#define op_intf_to_buf(C, val, def, cond) do { \ + if ((cond)) \ + { \ + colon_to_buf; \ + char_to_buf((C)); \ + if ((val) != (def)) int_to_buf(val); \ + } \ + } while (0) +#define op_str_to_buf(C, val, cond) do { \ + if ((cond)) \ + { \ + char *s=(val); \ + colon_to_buf; \ + char_to_buf((C)); \ + if (*s) str_to_buf(s); \ + } \ + } while (0) +#define op_list_to_buf(C, val, cond) do { \ + if ((cond)) \ + { \ + colon_to_buf; \ + char_to_buf((C)); \ + list_to_buf(val); \ + } \ + } while (0) +#define op_bool_to_buf(C, cond) do { \ + if ((cond)) \ + { \ + colon_to_buf; \ + char_to_buf((C)); \ + } \ + } while (0) + +int _db_explain_ (CODE_STATE *cs, char *buf, int len) +{ + char *start=buf, *end=buf+len-4; + + get_code_state_or_return *buf=0; + + op_list_to_buf('d', cs->stack->keywords, DEBUGGING); + op_int_to_buf ('D', cs->stack->delay, 0); + op_list_to_buf('f', cs->stack->functions, cs->stack->functions); + op_bool_to_buf('F', cs->stack->flags & FILE_ON); + op_bool_to_buf('i', cs->stack->flags & PID_ON); + op_list_to_buf('g', cs->stack->p_functions, PROFILING); + op_bool_to_buf('L', cs->stack->flags & LINE_ON); + op_bool_to_buf('n', cs->stack->flags & DEPTH_ON); + op_bool_to_buf('N', cs->stack->flags & NUMBER_ON); + op_str_to_buf( + ((cs->stack->flags & FLUSH_ON_WRITE ? 0 : 32) | + (cs->stack->flags & OPEN_APPEND ? 'A' : 'O')), + cs->stack->name, cs->stack->out_file != stderr); + op_list_to_buf('p', cs->stack->processes, cs->stack->processes); + op_bool_to_buf('P', cs->stack->flags & PROCESS_ON); + op_bool_to_buf('r', cs->stack->sub_level != 0); + op_intf_to_buf('t', cs->stack->maxdepth, MAXDEPTH, TRACING); + op_bool_to_buf('S', cs->stack->flags & SANITY_CHECK_ON); + + *buf= '\0'; + return 0; + +overflow: + *end++= '.'; + *end++= '.'; + *end++= '.'; + *end= '\0'; + return 1; +} + +#undef char_to_buf +#undef str_to_buf +#undef list_to_buf +#undef int_to_buf +#undef colon_to_buf +#undef op_int_to_buf +#undef op_intf_to_buf +#undef op_str_to_buf +#undef op_list_to_buf +#undef op_bool_to_buf + +/* + * FUNCTION + * + * _db_explain_init_ explain initial debugger settings + * + * DESCRIPTION + * see _db_explain_ + */ + +int _db_explain_init_(char *buf, int len) +{ + CODE_STATE cs; + bzero((char*) &cs,sizeof(cs)); + cs.stack=&init_settings; + return _db_explain_(&cs, buf, len); +} + +/* + * FUNCTION + * + * _db_enter_ process entry point to user function + * + * SYNOPSIS + * + * VOID _db_enter_(_func_, _file_, _line_, + * _sfunc_, _sfile_, _slevel_, _sframep_) + * char *_func_; points to current function name + * char *_file_; points to current file name + * int _line_; called from source line number + * char **_sfunc_; save previous _func_ + * char **_sfile_; save previous _file_ + * int *_slevel_; save previous nesting level + * char ***_sframep_; save previous frame pointer + * + * DESCRIPTION + * + * Called at the beginning of each user function to tell + * the debugger that a new function has been entered. + * Note that the pointers to the previous user function + * name and previous user file name are stored on the + * caller's stack (this is why the ENTER macro must be + * the first "executable" code in a function, since it + * allocates these storage locations). The previous nesting + * level is also stored on the callers stack for internal + * self consistency checks. + * + * Also prints a trace line if tracing is enabled and + * increments the current function nesting depth. + * + * Note that this mechanism allows the debugger to know + * what the current user function is at all times, without + * maintaining an internal stack for the function names. + * + */ + +void _db_enter_(const char *_func_, const char *_file_, + uint _line_, const char **_sfunc_, const char **_sfile_, + uint *_slevel_, char ***_sframep_ __attribute__((unused))) +{ + int save_errno=errno; + CODE_STATE *cs=0; + get_code_state_or_return; + + *_sfunc_= cs->func; + *_sfile_= cs->file; + cs->func= _func_; + cs->file= _file_; + *_slevel_= ++cs->level; +#ifndef THREAD + *_sframep_= cs->framep; + cs->framep= (char **) _sframep_; + if (DoProfile(cs)) + { + long stackused; + if (*cs->framep == NULL) + stackused= 0; + else + { + stackused= ((long)(*cs->framep)) - ((long)(cs->framep)); + stackused= stackused > 0 ? stackused : -stackused; } - 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); - if (!(stack->flags & DEBUG_ON)) - _db_on_=0; + (void) fprintf(cs->stack->prof_file, PROF_EFMT , Clock(), cs->func); +#ifdef AUTOS_REVERSE + (void) fprintf(cs->stack->prof_file, PROF_SFMT, cs->framep, stackused, *_sfunc_); +#else + (void) fprintf(cs->stack->prof_file, PROF_SFMT, (ulong) cs->framep, stackused, + cs->func); +#endif + (void) fflush(cs->stack->prof_file); + } +#endif + if (DoTrace(cs)) + { + if (!cs->locked) + pthread_mutex_lock(&THR_LOCK_dbug); + DoPrefix(cs, _line_); + Indent(cs, cs->level); + (void) fprintf(cs->stack->out_file, ">%s\n", cs->func); + dbug_flush(cs); /* This does a unlock */ + } +#ifdef SAFEMALLOC + if (cs->stack->flags & SANITY_CHECK_ON) + if (_sanity(_file_,_line_)) /* Check of safemalloc */ + cs->stack->flags &= ~SANITY_CHECK_ON; +#endif + errno=save_errno; +} + +/* + * FUNCTION + * + * _db_return_ process exit from user function + * + * SYNOPSIS + * + * VOID _db_return_(_line_, _sfunc_, _sfile_, _slevel_) + * int _line_; current source line number + * char **_sfunc_; where previous _func_ is to be retrieved + * char **_sfile_; where previous _file_ is to be retrieved + * int *_slevel_; where previous level was stashed + * + * DESCRIPTION + * + * Called just before user function executes an explicit or implicit + * return. Prints a trace line if trace is enabled, decrements + * the current nesting level, and restores the current function and + * file names from the defunct function's stack. + * + */ + +/* helper macro */ +void _db_return_(uint _line_, const char **_sfunc_, + const char **_sfile_, uint *_slevel_) +{ + int save_errno=errno; + CODE_STATE *cs=0; + get_code_state_or_return; + + if (cs->level != (int) *_slevel_) + { + if (!cs->locked) + pthread_mutex_lock(&THR_LOCK_dbug); + (void) fprintf(cs->stack->out_file, ERR_MISSING_RETURN, cs->process, + cs->func); + dbug_flush(cs); } else { - _db_on_=0; - } -} - - -/* - * FUNCTION - * - * _db_enter_ process entry point to user function - * - * SYNOPSIS - * - * VOID _db_enter_ (_func_, _file_, _line_, - * _sfunc_, _sfile_, _slevel_, _sframep_) - * char *_func_; points to current function name - * char *_file_; points to current file name - * int _line_; called from source line number - * char **_sfunc_; save previous _func_ - * char **_sfile_; save previous _file_ - * int *_slevel_; save previous nesting level - * char ***_sframep_; save previous frame pointer - * - * DESCRIPTION - * - * Called at the beginning of each user function to tell - * the debugger that a new function has been entered. - * Note that the pointers to the previous user function - * name and previous user file name are stored on the - * caller's stack (this is why the ENTER macro must be - * the first "executable" code in a function, since it - * allocates these storage locations). The previous nesting - * level is also stored on the callers stack for internal - * self consistency checks. - * - * Also prints a trace line if tracing is enabled and - * increments the current function nesting depth. - * - * Note that this mechanism allows the debugger to know - * what the current user function is at all times, without - * maintaining an internal stack for the function names. - * - */ - -void _db_enter_ ( -const char *_func_, -const char *_file_, -uint _line_, -const char **_sfunc_, -const char **_sfile_, -uint *_slevel_, -char ***_sframep_ __attribute__((unused))) -{ - reg1 CODE_STATE *state; - - if (!_no_db_) - { - int save_errno=errno; - /* - Sasha: the test below is so we could call functions with DBUG_ENTER - before my_thread_init(). I needed this because I suspected corruption - of a block allocated by my_thread_init() itself, so I wanted to use - my_malloc()/my_free() in my_thread_init()/my_thread_end() - */ - if (!(state=code_state())) - return; - if (!init_done) - _db_push_ (_DBUG_START_CONDITION_); - - *_sfunc_ = state->func; - *_sfile_ = state->file; - state->func =(char*) _func_; - state->file = (char*) _file_; /* BaseName takes time !! */ - *_slevel_ = ++state->level; -#ifndef THREAD - *_sframep_ = state->framep; - state->framep = (char **) _sframep_; - if (DoProfile ()) - { - long stackused; - if (*state->framep == NULL) - { - stackused = 0; - } - else - { - stackused = ((long)(*state->framep)) - ((long)(state->framep)); - stackused = stackused > 0 ? stackused : -stackused; - } - (void) fprintf (_db_pfp_, PROF_EFMT , Clock (), state->func); -#ifdef AUTOS_REVERSE - (void) fprintf (_db_pfp_, PROF_SFMT, state->framep, stackused, *_sfunc_); -#else - (void) fprintf (_db_pfp_, PROF_SFMT, (ulong) state->framep, stackused, - state->func); -#endif - (void) fflush (_db_pfp_); - } -#endif - if (DoTrace(state)) - { - if (!state->locked) - pthread_mutex_lock(&THR_LOCK_dbug); - DoPrefix (_line_); - Indent (state -> level); - (void) fprintf (_db_fp_, ">%s\n", state->func); - dbug_flush (state); /* This does a unlock */ - } #ifdef SAFEMALLOC - if (stack->flags & SANITY_CHECK_ON && !state->disable_output) - if (_sanity(_file_,_line_)) /* Check of safemalloc */ - stack -> flags &= ~SANITY_CHECK_ON; -#endif - errno=save_errno; - } -} - -/* - * FUNCTION - * - * _db_return_ process exit from user function - * - * SYNOPSIS - * - * VOID _db_return_ (_line_, _sfunc_, _sfile_, _slevel_) - * int _line_; current source line number - * char **_sfunc_; where previous _func_ is to be retrieved - * char **_sfile_; where previous _file_ is to be retrieved - * int *_slevel_; where previous level was stashed - * - * DESCRIPTION - * - * Called just before user function executes an explicit or implicit - * return. Prints a trace line if trace is enabled, decrements - * the current nesting level, and restores the current function and - * file names from the defunct function's stack. - * - */ - -void _db_return_ ( -uint _line_, -const char **_sfunc_, -const char **_sfile_, -uint *_slevel_) -{ - CODE_STATE *state; - - if (!_no_db_) - { - int save_errno=errno; - if (!(state=code_state())) - return; - if (!init_done) - _db_push_ (""); - if (stack->flags & (TRACE_ON | DEBUG_ON | PROFILE_ON)) + if (cs->stack->flags & SANITY_CHECK_ON) { - if (!state->locked) - pthread_mutex_lock(&THR_LOCK_dbug); - if (state->level != (int) *_slevel_) - (void) fprintf (_db_fp_, ERR_MISSING_RETURN, _db_process_, - state->func); - else - { -#ifdef SAFEMALLOC - if (stack->flags & SANITY_CHECK_ON && !state->disable_output) - { - if (_sanity(*_sfile_,_line_)) - stack->flags &= ~SANITY_CHECK_ON; - } -#endif -#ifndef THREAD - if (DoProfile ()) - (void) fprintf (_db_pfp_, PROF_XFMT, Clock(), state->func); -#endif - if (DoTrace (state)) - { - DoPrefix (_line_); - Indent (state->level); - (void) fprintf (_db_fp_, "<%s\n", state->func); - } - } - dbug_flush(state); + if (_sanity(*_sfile_,_line_)) + cs->stack->flags &= ~SANITY_CHECK_ON; } - state->level = *_slevel_-1; - state->func = *_sfunc_; - state->file = *_sfile_; -#ifndef THREAD - if (state->framep != NULL) - state->framep = (char **) *state->framep; #endif - errno=save_errno; +#ifndef THREAD + if (DoProfile(cs)) + (void) fprintf(cs->stack->prof_file, PROF_XFMT, Clock(), cs->func); +#endif + if (DoTrace(cs)) + { + if (!cs->locked) + pthread_mutex_lock(&THR_LOCK_dbug); + DoPrefix(cs, _line_); + Indent(cs, cs->level); + (void) fprintf(cs->stack->out_file, "<%s\n", cs->func); + dbug_flush(cs); + } } + cs->level= *_slevel_-1; + cs->func= *_sfunc_; + cs->file= *_sfile_; +#ifndef THREAD + if (cs->framep != NULL) + cs->framep= (char **) *cs->framep; +#endif + errno=save_errno; } /* * FUNCTION * - * _db_pargs_ log arguments for subsequent use by _db_doprnt_() + * _db_pargs_ log arguments for subsequent use by _db_doprnt_() * * SYNOPSIS * - * VOID _db_pargs_ (_line_, keyword) - * int _line_; - * char *keyword; + * VOID _db_pargs_(_line_, keyword) + * int _line_; + * char *keyword; * * DESCRIPTION * - * The new universal printing macro DBUG_PRINT, which replaces - * all forms of the DBUG_N macros, needs two calls to runtime - * support routines. The first, this function, remembers arguments - * that are used by the subsequent call to _db_doprnt_(). + * The new universal printing macro DBUG_PRINT, which replaces + * all forms of the DBUG_N macros, needs two calls to runtime + * support routines. The first, this function, remembers arguments + * that are used by the subsequent call to _db_doprnt_(). * */ -void _db_pargs_ ( -uint _line_, -const char *keyword) +void _db_pargs_(uint _line_, const char *keyword) { - CODE_STATE *state=code_state(); - /* Sasha: pre-my_thread_init() safety */ - if (!state) - return; - state->u_line = _line_; - state->u_keyword = (char*) keyword; + CODE_STATE *cs=0; + get_code_state_or_return; + cs->u_line= _line_; + cs->u_keyword= (char*) keyword; } /* * FUNCTION * - * _db_doprnt_ handle print of debug lines + * _db_doprnt_ handle print of debug lines * * SYNOPSIS * - * VOID _db_doprnt_ (format, va_alist) - * char *format; - * va_dcl; + * VOID _db_doprnt_(format, va_alist) + * char *format; + * va_dcl; * * DESCRIPTION * - * When invoked via one of the DBUG macros, tests the current keyword - * set by calling _db_pargs_() to see if that macro has been selected - * for processing via the debugger control string, and if so, handles - * printing of the arguments via the format string. The line number - * of the DBUG macro in the source is found in u_line. + * When invoked via one of the DBUG macros, tests the current keyword + * set by calling _db_pargs_() to see if that macro has been selected + * for processing via the debugger control string, and if so, handles + * printing of the arguments via the format string. The line number + * of the DBUG macro in the source is found in u_line. * - * Note that the format string SHOULD NOT include a terminating - * newline, this is supplied automatically. + * Note that the format string SHOULD NOT include a terminating + * newline, this is supplied automatically. * */ #include -void _db_doprnt_ (const char *format,...) +void _db_doprnt_(const char *format,...) { va_list args; - CODE_STATE *state; - /* Sasha: pre-my_thread_init() safety */ - if (!(state=code_state())) - return; + + CODE_STATE *cs=0; + get_code_state_or_return; va_start(args,format); - if (_db_keyword_ (state->u_keyword)) { + if (_db_keyword_(cs, cs->u_keyword)) + { int save_errno=errno; - if (!state->locked) + if (!cs->locked) pthread_mutex_lock(&THR_LOCK_dbug); - DoPrefix (state->u_line); - if (TRACING) { - Indent (state->level + 1); - } else { - (void) fprintf (_db_fp_, "%s: ", state->func); - } - (void) fprintf (_db_fp_, "%s: ", state->u_keyword); - (void) vfprintf (_db_fp_, format, args); - (void) fputc('\n',_db_fp_); - dbug_flush(state); + DoPrefix(cs, cs->u_line); + if (TRACING) + Indent(cs, cs->level + 1); + else + (void) fprintf(cs->stack->out_file, "%s: ", cs->func); + (void) fprintf(cs->stack->out_file, "%s: ", cs->u_keyword); + (void) vfprintf(cs->stack->out_file, format, args); + (void) fputc('\n',cs->stack->out_file); + dbug_flush(cs); errno=save_errno; } va_end(args); @@ -941,46 +1152,42 @@ void _db_doprnt_ (const char *format,...) * * SYNOPSIS * - * void _db_dump_ (_line_,keyword,memory,length) - * int _line_; current source line number - * char *keyword; - * char *memory; Memory to print - * int length; Bytes to print + * void _db_dump_(_line_,keyword,memory,length) + * int _line_; current source line number + * char *keyword; + * char *memory; Memory to print + * int length; Bytes to print * * DESCRIPTION * Dump N characters in a binary array. * Is used to examine corrputed memory or arrays. */ -void _db_dump_( -uint _line_, -const char *keyword, -const char *memory, -uint length) +void _db_dump_(uint _line_, const char *keyword, const char *memory, uint length) { int pos; char dbuff[90]; - CODE_STATE *state; - if (!(state=code_state())) - return; - if (_db_keyword_ ((char*) keyword)) + CODE_STATE *cs=0; + get_code_state_or_return; + + if (_db_keyword_(cs, (char*) keyword)) { - if (!state->locked) + if (!cs->locked) pthread_mutex_lock(&THR_LOCK_dbug); - DoPrefix (_line_); + DoPrefix(cs, _line_); if (TRACING) { - Indent (state->level + 1); - pos= min(max(state->level-stack->sub_level,0)*INDENT,80); + Indent(cs, cs->level + 1); + pos= min(max(cs->level-cs->stack->sub_level,0)*INDENT,80); } else { - fprintf(_db_fp_, "%s: ", state->func); + fprintf(cs->stack->out_file, "%s: ", cs->func); } sprintf(dbuff,"%s: Memory: 0x%lx Bytes: (%d)\n", - keyword,(ulong) memory, length); - (void) fputs(dbuff,_db_fp_); + keyword,(ulong) memory, length); + (void) fputs(dbuff,cs->stack->out_file); pos=0; while (length-- > 0) @@ -988,247 +1195,298 @@ uint length) uint tmp= *((unsigned char*) memory++); if ((pos+=3) >= 80) { - fputc('\n',_db_fp_); - pos=3; + fputc('\n',cs->stack->out_file); + pos=3; } - fputc(_dig_vec_upper[((tmp >> 4) & 15)], _db_fp_); - fputc(_dig_vec_upper[tmp & 15], _db_fp_); - fputc(' ',_db_fp_); + fputc(_dig_vec_upper[((tmp >> 4) & 15)], cs->stack->out_file); + fputc(_dig_vec_upper[tmp & 15], cs->stack->out_file); + fputc(' ',cs->stack->out_file); } - (void) fputc('\n',_db_fp_); - dbug_flush(state); + (void) fputc('\n',cs->stack->out_file); + dbug_flush(cs); } } -/* - Enable/Disable output for this thread - - SYNOPSIS - _db_output_() - flag 1 = enable output, 0 = disable_output - -*/ - -void _db_output_(uint flag) -{ - CODE_STATE *state; - if (!(state=code_state())) - return; - state->disable_output= !flag; -} - - /* * FUNCTION * - * ListParse parse list of modifiers in debug control string + * ListAdd add to the list modifiers from debug control string * * SYNOPSIS * - * static struct link *ListParse (ctlp) - * char *ctlp; + * static struct link *ListAdd(listp, ctlp, end) + * struct link *listp; + * char *ctlp; + * char *end; * * DESCRIPTION * - * Given pointer to a comma separated list of strings in "cltp", - * parses the list, building a list and returning a pointer to it. - * The original comma separated list is destroyed in the process of - * building the linked list, thus it had better be a duplicate - * if it is important. + * Given pointer to a comma separated list of strings in "cltp", + * parses the list, and adds it to listp, returning a pointer + * to the new list * - * Note that since each link is added at the head of the list, - * the final list will be in "reverse order", which is not - * significant for our usage here. + * Note that since each link is added at the head of the list, + * the final list will be in "reverse order", which is not + * significant for our usage here. * */ -static struct link *ListParse ( -char *ctlp) +static struct link *ListAdd(struct link *head, + const char *ctlp, const char *end) { - REGISTER char *start; - REGISTER struct link *new_malloc; - REGISTER struct link *head; + const char *start; + struct link *new_malloc; + int len; - head = NULL; - while (*ctlp != EOS) { - start = ctlp; - while (*ctlp != EOS && *ctlp != ',') { + while (ctlp < end) + { + start= ctlp; + while (ctlp < end && *ctlp != ',') ctlp++; - } - if (*ctlp == ',') { - *ctlp++ = EOS; - } - new_malloc = (struct link *) DbugMalloc (sizeof (struct link)); - new_malloc -> str = StrDup (start); - new_malloc -> next_link = head; - head = new_malloc; + len=ctlp-start; + new_malloc= (struct link *) DbugMalloc(sizeof(struct link)+len); + memcpy(new_malloc->str, start, len); + new_malloc->str[len]=0; + new_malloc->next_link= head; + head= new_malloc; + ctlp++; } - return (head); + return head; } /* * FUNCTION * - * InList test a given string for member of a given list + * ListDel remove from the list modifiers in debug control string * * SYNOPSIS * - * static BOOLEAN InList (linkp, cp) - * struct link *linkp; - * char *cp; + * static struct link *ListDel(listp, ctlp, end) + * struct link *listp; + * char *ctlp; + * char *end; * * DESCRIPTION * - * Tests the string pointed to by "cp" to determine if it is in - * the list pointed to by "linkp". Linkp points to the first - * link in the list. If linkp is NULL then the string is treated - * as if it is in the list (I.E all strings are in the null list). - * This may seem rather strange at first but leads to the desired - * operation if no list is given. The net effect is that all - * strings will be accepted when there is no list, and when there - * is a list, only those strings in the list will be accepted. + * Given pointer to a comma separated list of strings in "cltp", + * parses the list, and removes these strings from the listp, + * returning a pointer to the new list. * */ -static BOOLEAN InList ( -struct link *linkp, -const char *cp) +static struct link *ListDel(struct link *head, + const char *ctlp, const char *end) +{ + const char *start; + struct link **cur; + int len; + + while (ctlp < end) + { + start= ctlp; + while (ctlp < end && *ctlp != ',') + ctlp++; + len=ctlp-start; + cur=&head; + do + { + while (*cur && !strncmp((*cur)->str, start, len)) + { + struct link *delme=*cur; + *cur=(*cur)->next_link; + free((char*)delme); + } + } while (*cur && *(cur=&((*cur)->next_link))); + } + return head; +} + +/* + * FUNCTION + * + * ListCopy make a copy of the list + * + * SYNOPSIS + * + * static struct link *ListCopy(orig) + * struct link *orig; + * + * DESCRIPTION + * + * Given pointer to list, which contains a copy of every element from + * the original list. + * + * the orig pointer can be NULL + * + * Note that since each link is added at the head of the list, + * the final list will be in "reverse order", which is not + * significant for our usage here. + * + */ + +static struct link *ListCopy(struct link *orig) +{ + struct link *new_malloc; + struct link *head; + int len; + + head= NULL; + while (orig != NULL) + { + len= strlen(orig->str); + new_malloc= (struct link *) DbugMalloc(sizeof(struct link)+len); + memcpy(new_malloc->str, orig->str, len); + new_malloc->str[len]= 0; + new_malloc->next_link= head; + head= new_malloc; + orig= orig->next_link; + } + return head; +} + +/* + * FUNCTION + * + * InList test a given string for member of a given list + * + * SYNOPSIS + * + * static BOOLEAN InList(linkp, cp) + * struct link *linkp; + * char *cp; + * + * DESCRIPTION + * + * Tests the string pointed to by "cp" to determine if it is in + * the list pointed to by "linkp". Linkp points to the first + * link in the list. If linkp is NULL then the string is treated + * as if it is in the list (I.E all strings are in the null list). + * This may seem rather strange at first but leads to the desired + * operation if no list is given. The net effect is that all + * strings will be accepted when there is no list, and when there + * is a list, only those strings in the list will be accepted. + * + */ + +static BOOLEAN InList(struct link *linkp, const char *cp) { REGISTER struct link *scan; REGISTER BOOLEAN result; - if (linkp == NULL) { - result = TRUE; - } else { - result = FALSE; - for (scan = linkp; scan != NULL; scan = scan -> next_link) { - if (STREQ (scan -> str, cp)) { - result = TRUE; - break; + if (linkp == NULL) + result= TRUE; + else + { + result= FALSE; + for (scan= linkp; scan != NULL; scan= scan->next_link) + { + if (!strcmp(scan->str, cp)) + { + result= TRUE; + break; } } } - return (result); + return result; } /* * FUNCTION * - * PushState push current state onto stack and set up new one + * PushState push current settings onto stack and set up new one * * SYNOPSIS * - * static VOID PushState () + * static VOID PushState() * * DESCRIPTION * - * Pushes the current state on the state stack, and initializes - * a new state. The only parameter inherited from the previous - * state is the function nesting level. This action can be - * inhibited if desired, via the "r" flag. + * Pushes the current settings on the settings stack, and creates + * a new settings. The new settings is NOT initialized * - * The state stack is a linked list of states, with the new - * state added at the head. This allows the stack to grow - * to the limits of memory if necessary. + * The settings stack is a linked list of settings, with the new + * settings added at the head. This allows the stack to grow + * to the limits of memory if necessary. * */ -static void PushState () +static void PushState(CODE_STATE *cs) { - REGISTER struct state *new_malloc; + struct settings *new_malloc; - if (!init_done) - { - init_dbug_state(); - init_done=TRUE; - } - (void) code_state(); /* Alloc memory */ - new_malloc = (struct state *) DbugMalloc(sizeof (struct state)); - new_malloc -> flags = 0; - new_malloc -> delay = 0; - new_malloc -> maxdepth = MAXDEPTH; - new_malloc -> sub_level=0; - new_malloc -> out_file = stderr; - new_malloc -> prof_file = (FILE*) 0; - new_malloc -> functions = NULL; - new_malloc -> p_functions = NULL; - new_malloc -> keywords = NULL; - new_malloc -> processes = NULL; - new_malloc -> next_state = stack; - stack=new_malloc; + new_malloc= (struct settings *) DbugMalloc(sizeof(struct settings)); + new_malloc->next= cs->stack; + new_malloc->out_file= NULL; + cs->stack= new_malloc; } /* * FUNCTION * - * DoTrace check to see if tracing is current enabled + * DoTrace check to see if tracing is current enabled * * SYNOPSIS * - * static BOOLEAN DoTrace (stack) + * static BOOLEAN DoTrace(stack) * * DESCRIPTION * - * Checks to see if tracing is enabled based on whether the - * user has specified tracing, the maximum trace depth has - * not yet been reached, the current function is selected, - * and the current process is selected. Returns TRUE if - * tracing is enabled, FALSE otherwise. + * Checks to see if tracing is enabled based on whether the + * user has specified tracing, the maximum trace depth has + * not yet been reached, the current function is selected, + * and the current process is selected. Returns TRUE if + * tracing is enabled, FALSE otherwise. * */ -static BOOLEAN DoTrace (CODE_STATE *state) +static BOOLEAN DoTrace(CODE_STATE *cs) { - reg2 BOOLEAN trace=FALSE; - - if (TRACING && !state->disable_output && - state->level <= stack -> maxdepth && - InList (stack -> functions, state->func) && - InList (stack -> processes, _db_process_)) - trace = TRUE; - return (trace); + return (TRACING && cs->level <= cs->stack->maxdepth && + InList(cs->stack->functions, cs->func) && + InList(cs->stack->processes, cs->process)); } /* * FUNCTION * - * DoProfile check to see if profiling is current enabled + * DoProfile check to see if profiling is current enabled * * SYNOPSIS * - * static BOOLEAN DoProfile () + * static BOOLEAN DoProfile() * * DESCRIPTION * - * Checks to see if profiling is enabled based on whether the - * user has specified profiling, the maximum trace depth has - * not yet been reached, the current function is selected, - * and the current process is selected. Returns TRUE if - * profiling is enabled, FALSE otherwise. + * Checks to see if profiling is enabled based on whether the + * user has specified profiling, the maximum trace depth has + * not yet been reached, the current function is selected, + * and the current process is selected. Returns TRUE if + * profiling is enabled, FALSE otherwise. * */ #ifndef THREAD -static BOOLEAN DoProfile () +static BOOLEAN DoProfile(CODE_STATE *cs) { - REGISTER BOOLEAN profile; - CODE_STATE *state; - state=code_state(); - - profile = FALSE; - if (PROFILING && !state->disable_output && - state->level <= stack -> maxdepth && - InList (stack -> p_functions, state->func) && - InList (stack -> processes, _db_process_)) - profile = TRUE; - return (profile); + return PROFILING && + cs->level <= cs->stack->maxdepth && + InList(cs->stack->p_functions, cs->func) && + InList(cs->stack->processes, cs->process); } #endif +FILE *_db_fp_(void) +{ + CODE_STATE *cs=0; + get_code_state_or_return NULL; + return cs->stack->out_file; +} + + /* * FUNCTION * @@ -1236,7 +1494,7 @@ static BOOLEAN DoProfile () * * SYNOPSIS * - * BOOLEAN _db_strict_keyword_ (keyword) + * BOOLEAN _db_strict_keyword_(keyword) * char *keyword; * * DESCRIPTION @@ -1249,93 +1507,83 @@ static BOOLEAN DoProfile () * */ -BOOLEAN _db_strict_keyword_ ( -const char *keyword) +BOOLEAN _db_strict_keyword_(const char *keyword) { - if (stack -> keywords == NULL) + CODE_STATE *cs=0; + get_code_state_or_return FALSE; + if (!DEBUGGING || cs->stack->keywords == NULL) return FALSE; - return _db_keyword_ (keyword); + return _db_keyword_(cs, keyword); } /* * FUNCTION * - * _db_keyword_ test keyword for member of keyword list + * _db_keyword_ test keyword for member of keyword list * * SYNOPSIS * - * BOOLEAN _db_keyword_ (keyword) - * char *keyword; + * BOOLEAN _db_keyword_(keyword) + * char *keyword; * * DESCRIPTION * - * Test a keyword to determine if it is in the currently active - * keyword list. As with the function list, a keyword is accepted - * if the list is null, otherwise it must match one of the list - * members. When debugging is not on, no keywords are accepted. - * After the maximum trace level is exceeded, no keywords are - * accepted (this behavior subject to change). Additionally, - * the current function and process must be accepted based on - * their respective lists. + * Test a keyword to determine if it is in the currently active + * keyword list. As with the function list, a keyword is accepted + * if the list is null, otherwise it must match one of the list + * members. When debugging is not on, no keywords are accepted. + * After the maximum trace level is exceeded, no keywords are + * accepted (this behavior subject to change). Additionally, + * the current function and process must be accepted based on + * their respective lists. * - * Returns TRUE if keyword accepted, FALSE otherwise. + * Returns TRUE if keyword accepted, FALSE otherwise. * */ -BOOLEAN _db_keyword_ ( -const char *keyword) +BOOLEAN _db_keyword_(CODE_STATE *cs, const char *keyword) { - REGISTER BOOLEAN result; - CODE_STATE *state; + get_code_state_or_return FALSE; - if (!init_done) - _db_push_ (""); - /* Sasha: pre-my_thread_init() safety */ - if (!(state=code_state())) - return FALSE; - result = FALSE; - if (DEBUGGING && !state->disable_output && - state->level <= stack -> maxdepth && - InList (stack -> functions, state->func) && - InList (stack -> keywords, keyword) && - InList (stack -> processes, _db_process_)) - result = TRUE; - return (result); + return (DEBUGGING && + (!TRACING || cs->level <= cs->stack->maxdepth) && + InList(cs->stack->functions, cs->func) && + InList(cs->stack->keywords, keyword) && + InList(cs->stack->processes, cs->process)); } /* * FUNCTION * - * Indent indent a line to the given indentation level + * Indent indent a line to the given indentation level * * SYNOPSIS * - * static VOID Indent (indent) - * int indent; + * static VOID Indent(indent) + * int indent; * * DESCRIPTION * - * Indent a line to the given level. Note that this is - * a simple minded but portable implementation. - * There are better ways. + * Indent a line to the given level. Note that this is + * a simple minded but portable implementation. + * There are better ways. * - * Also, the indent must be scaled by the compile time option - * of character positions per nesting level. + * Also, the indent must be scaled by the compile time option + * of character positions per nesting level. * */ -static void Indent ( -int indent) +static void Indent(CODE_STATE *cs, int indent) { REGISTER int count; - indent= max(indent-1-stack->sub_level,0)*INDENT; - for (count = 0; count < indent ; count++) + indent= max(indent-1-cs->stack->sub_level,0)*INDENT; + for (count= 0; count < indent ; count++) { if ((count % INDENT) == 0) - fputc('|',_db_fp_); + fputc('|',cs->stack->out_file); else - fputc(' ',_db_fp_); + fputc(' ',cs->stack->out_file); } } @@ -1343,32 +1591,29 @@ int indent) /* * FUNCTION * - * FreeList free all memory associated with a linked list + * FreeList free all memory associated with a linked list * * SYNOPSIS * - * static VOID FreeList (linkp) - * struct link *linkp; + * static VOID FreeList(linkp) + * struct link *linkp; * * DESCRIPTION * - * Given pointer to the head of a linked list, frees all - * memory held by the list and the members of the list. + * Given pointer to the head of a linked list, frees all + * memory held by the list and the members of the list. * */ -static void FreeList ( -struct link *linkp) +static void FreeList(struct link *linkp) { REGISTER struct link *old; - while (linkp != NULL) { - old = linkp; - linkp = linkp -> next_link; - if (old -> str != NULL) { - free (old -> str); - } - free ((char *) old); + while (linkp != NULL) + { + old= linkp; + linkp= linkp->next_link; + free((char *) old); } } @@ -1376,139 +1621,128 @@ struct link *linkp) /* * FUNCTION * - * StrDup make a duplicate of a string in new memory + * DoPrefix print debugger line prefix prior to indentation * * SYNOPSIS * - * static char *StrDup (my_string) - * char *string; + * static VOID DoPrefix(_line_) + * int _line_; * * DESCRIPTION * - * Given pointer to a string, allocates sufficient memory to make - * a duplicate copy, and copies the string to the newly allocated - * memory. Failure to allocated sufficient memory is immediately - * fatal. + * Print prefix common to all debugger output lines, prior to + * doing indentation if necessary. Print such information as + * current process name, current source file name and line number, + * and current function nesting depth. * */ - -static char *StrDup (const char *str) +static void DoPrefix(CODE_STATE *cs, uint _line_) { - reg1 char *new_malloc; - new_malloc = DbugMalloc((size_t) strlen (str) + 1); - (void) strcpy (new_malloc, str); - return (new_malloc); -} - - -/* - * FUNCTION - * - * DoPrefix print debugger line prefix prior to indentation - * - * SYNOPSIS - * - * static VOID DoPrefix (_line_) - * int _line_; - * - * DESCRIPTION - * - * Print prefix common to all debugger output lines, prior to - * doing indentation if necessary. Print such information as - * current process name, current source file name and line number, - * and current function nesting depth. - * - */ - -static void DoPrefix ( -uint _line_) -{ - CODE_STATE *state; - state=code_state(); - - state->lineno++; - if (stack -> flags & PID_ON) { + cs->lineno++; + if (cs->stack->flags & PID_ON) + { #ifdef THREAD - (void) fprintf (_db_fp_, "%-7s: ", my_thread_name()); + (void) fprintf(cs->stack->out_file, "%-7s: ", my_thread_name()); #else - (void) fprintf (_db_fp_, "%5d: ", (int) getpid ()); + (void) fprintf(cs->stack->out_file, "%5d: ", (int) getpid()); #endif } - if (stack -> flags & NUMBER_ON) { - (void) fprintf (_db_fp_, "%5d: ", state->lineno); - } - if (stack -> flags & PROCESS_ON) { - (void) fprintf (_db_fp_, "%s: ", _db_process_); - } - if (stack -> flags & FILE_ON) { - (void) fprintf (_db_fp_, "%14s: ", BaseName(state->file)); - } - if (stack -> flags & LINE_ON) { - (void) fprintf (_db_fp_, "%5d: ", _line_); - } - if (stack -> flags & DEPTH_ON) { - (void) fprintf (_db_fp_, "%4d: ", state->level); + if (cs->stack->flags & NUMBER_ON) + (void) fprintf(cs->stack->out_file, "%5d: ", cs->lineno); + if (cs->stack->flags & TIMESTAMP_ON) + { + struct timeval tv; + struct tm *tm_p; + if (gettimeofday(&tv, NULL) != -1) + { + if ((tm_p= localtime(&tv.tv_sec))) + { + (void) fprintf (cs->stack->out_file, + /* "%04d-%02d-%02d " */ + "%02d:%02d:%02d.%06d ", + /*tm_p->tm_year + 1900, tm_p->tm_mon + 1, tm_p->tm_mday,*/ + tm_p->tm_hour, tm_p->tm_min, tm_p->tm_sec, + (int) (tv.tv_usec)); + } + } } + if (cs->stack->flags & PROCESS_ON) + (void) fprintf(cs->stack->out_file, "%s: ", cs->process); + if (cs->stack->flags & FILE_ON) + (void) fprintf(cs->stack->out_file, "%14s: ", BaseName(cs->file)); + if (cs->stack->flags & LINE_ON) + (void) fprintf(cs->stack->out_file, "%5d: ", _line_); + if (cs->stack->flags & DEPTH_ON) + (void) fprintf(cs->stack->out_file, "%4d: ", cs->level); } /* * FUNCTION * - * DBUGOpenFile open new output stream for debugger output + * DBUGOpenFile open new output stream for debugger output * * SYNOPSIS * - * static VOID DBUGOpenFile (name) - * char *name; + * static VOID DBUGOpenFile(name) + * char *name; * * DESCRIPTION * - * Given name of a new file (or "-" for stdout) opens the file - * and sets the output stream to the new file. + * Given name of a new file (or "-" for stdout) opens the file + * and sets the output stream to the new file. * */ -static void DBUGOpenFile (const char *name,int append) +static void DBUGOpenFile(CODE_STATE *cs, + const char *name,const char *end,int append) { REGISTER FILE *fp; REGISTER BOOLEAN newfile; if (name != NULL) { - strmov(stack->name,name); - if (strcmp (name, "-") == 0) + if (end) { - _db_fp_ = stdout; - stack -> out_file = _db_fp_; - stack -> flags |= FLUSH_ON_WRITE; + int len=end-name; + memcpy(cs->stack->name, name, len); + cs->stack->name[len]=0; + } + else + strmov(cs->stack->name,name); + name=cs->stack->name; + if (strcmp(name, "-") == 0) + { + cs->stack->out_file= stdout; + cs->stack->flags |= FLUSH_ON_WRITE; + cs->stack->name[0]=0; } else { if (!Writable((char*)name)) { - (void) fprintf (stderr, ERR_OPEN, _db_process_, name); - perror (""); - fflush(stderr); + (void) fprintf(stderr, ERR_OPEN, cs->process, name); + perror(""); + fflush(stderr); } else { - newfile= !EXISTS (name); - if (!(fp = fopen(name, append ? "a+" : "w"))) - { - (void) fprintf (stderr, ERR_OPEN, _db_process_, name); - perror (""); - fflush(stderr); - } - else - { - _db_fp_ = fp; - stack -> out_file = fp; - if (newfile) { - ChangeOwner (name); - } - } + newfile= !EXISTS(name); + if (!(fp= fopen(name, append ? "a+" : "w"))) + { + (void) fprintf(stderr, ERR_OPEN, cs->process, name); + perror(""); + fflush(stderr); + } + else + { + cs->stack->out_file= fp; + if (newfile) + { + ChangeOwner(cs, name); + } + } } } } @@ -1518,59 +1752,58 @@ static void DBUGOpenFile (const char *name,int append) /* * FUNCTION * - * OpenProfile open new output stream for profiler output + * OpenProfile open new output stream for profiler output * * SYNOPSIS * - * static FILE *OpenProfile (name) - * char *name; + * static FILE *OpenProfile(name) + * char *name; * * DESCRIPTION * - * Given name of a new file, opens the file - * and sets the profiler output stream to the new file. + * Given name of a new file, opens the file + * and sets the profiler output stream to the new file. * - * It is currently unclear whether the prefered behavior is - * to truncate any existing file, or simply append to it. - * The latter behavior would be desirable for collecting - * accumulated runtime history over a number of separate - * runs. It might take some changes to the analyzer program - * though, and the notes that Binayak sent with the profiling - * diffs indicated that append was the normal mode, but this - * does not appear to agree with the actual code. I haven't - * investigated at this time [fnf; 24-Jul-87]. + * It is currently unclear whether the prefered behavior is + * to truncate any existing file, or simply append to it. + * The latter behavior would be desirable for collecting + * accumulated runtime history over a number of separate + * runs. It might take some changes to the analyzer program + * though, and the notes that Binayak sent with the profiling + * diffs indicated that append was the normal mode, but this + * does not appear to agree with the actual code. I haven't + * investigated at this time [fnf; 24-Jul-87]. */ #ifndef THREAD -static FILE *OpenProfile (const char *name) +static FILE *OpenProfile(CODE_STATE *cs, const char *name) { REGISTER FILE *fp; REGISTER BOOLEAN newfile; fp=0; - if (!Writable (name)) + if (!Writable(name)) { - (void) fprintf (_db_fp_, ERR_OPEN, _db_process_, name); - perror (""); + (void) fprintf(cs->stack->out_file, ERR_OPEN, cs->process, name); + perror(""); dbug_flush(0); - (void) Delay (stack -> delay); + (void) Delay(cs->stack->delay); } else { - newfile= !EXISTS (name); - if (!(fp = fopen (name, "w"))) + newfile= !EXISTS(name); + if (!(fp= fopen(name, "w"))) { - (void) fprintf (_db_fp_, ERR_OPEN, _db_process_, name); - perror (""); + (void) fprintf(cs->stack->out_file, ERR_OPEN, cs->process, name); + perror(""); dbug_flush(0); } else { - _db_pfp_ = fp; - stack -> prof_file = fp; + cs->stack->prof_file= fp; if (newfile) { - ChangeOwner (name); + ChangeOwner(cs, name); } } } @@ -1581,30 +1814,28 @@ static FILE *OpenProfile (const char *name) /* * FUNCTION * - * CloseFile close the debug output stream + * DBUGCloseFile close the debug output stream * * SYNOPSIS * - * static VOID CloseFile (fp) - * FILE *fp; + * static VOID DBUGCloseFile(fp) + * FILE *fp; * * DESCRIPTION * - * Closes the debug output stream unless it is standard output - * or standard error. + * Closes the debug output stream unless it is standard output + * or standard error. * */ -static void CloseFile ( -FILE *fp) +static void DBUGCloseFile(CODE_STATE *cs, FILE *fp) { - if (fp != stderr && fp != stdout) { - if (fclose (fp) == EOF) { - pthread_mutex_lock(&THR_LOCK_dbug); - (void) fprintf (_db_fp_, ERR_CLOSE, _db_process_); - perror (""); - dbug_flush(0); - } + if (fp != stderr && fp != stdout && fclose(fp) == EOF) + { + pthread_mutex_lock(&THR_LOCK_dbug); + (void) fprintf(cs->stack->out_file, ERR_CLOSE, cs->process); + perror(""); + dbug_flush(0); } } @@ -1612,176 +1843,153 @@ FILE *fp) /* * FUNCTION * - * DbugExit print error message and exit + * DbugExit print error message and exit * * SYNOPSIS * - * static VOID DbugExit (why) - * char *why; + * static VOID DbugExit(why) + * char *why; * * DESCRIPTION * - * Prints error message using current process name, the reason for - * aborting (typically out of memory), and exits with status 1. - * This should probably be changed to use a status code - * defined in the user's debugger include file. + * Prints error message using current process name, the reason for + * aborting (typically out of memory), and exits with status 1. + * This should probably be changed to use a status code + * defined in the user's debugger include file. * */ -static void DbugExit (const char *why) +static void DbugExit(const char *why) { - (void) fprintf (stderr, ERR_ABORT, _db_process_, why); - (void) fflush (stderr); - exit (1); + CODE_STATE *cs=code_state(); + (void) fprintf(stderr, ERR_ABORT, cs ? cs->process : "(null)", why); + (void) fflush(stderr); + exit(1); } /* * FUNCTION * - * DbugMalloc allocate memory for debugger runtime support + * DbugMalloc allocate memory for debugger runtime support * * SYNOPSIS * - * static long *DbugMalloc (size) - * int size; + * static long *DbugMalloc(size) + * int size; * * DESCRIPTION * - * Allocate more memory for debugger runtime support functions. - * Failure to to allocate the requested number of bytes is - * immediately fatal to the current process. This may be - * rather unfriendly behavior. It might be better to simply - * print a warning message, freeze the current debugger state, - * and continue execution. + * Allocate more memory for debugger runtime support functions. + * Failure to to allocate the requested number of bytes is + * immediately fatal to the current process. This may be + * rather unfriendly behavior. It might be better to simply + * print a warning message, freeze the current debugger cs, + * and continue execution. * */ -static char *DbugMalloc (size_t size) +static char *DbugMalloc(size_t size) { register char *new_malloc; - if (!(new_malloc = (char*) malloc((size_t) size))) - DbugExit ("out of memory"); - return (new_malloc); + if (!(new_malloc= (char*) malloc((size_t) size))) + DbugExit("out of memory"); + return new_malloc; } /* - * As strtok but two separators in a row are changed to one - * separator (to allow directory-paths in dos). + * strtok lookalike - splits on ':', magically handles :\ and :/ */ -static char *static_strtok (char *s1, pchar separator) +static const char *DbugStrTok(const char *s) { - static char *end = NULL; - reg1 char *rtnval,*cpy; - - rtnval = NULL; - if (s1 != NULL) - end = s1; - if (end != NULL && *end != EOS) - { - rtnval=cpy=end; - do - { - if ((*cpy++ = *end++) == separator) - { - if (*end != separator) - { - cpy--; /* Point at separator */ - break; - } - end++; /* Two separators in a row, skip one */ - } - } while (*end != EOS); - *cpy=EOS; /* Replace last separator */ - } - return (rtnval); + while (s[0] && (s[0] != ':' || (s[1] == '\\' || s[1] == '/'))) + s++; + return s; } /* * FUNCTION * - * BaseName strip leading pathname components from name + * BaseName strip leading pathname components from name * * SYNOPSIS * - * static char *BaseName (pathname) - * char *pathname; + * static char *BaseName(pathname) + * char *pathname; * * DESCRIPTION * - * Given pointer to a complete pathname, locates the base file - * name at the end of the pathname and returns a pointer to - * it. + * Given pointer to a complete pathname, locates the base file + * name at the end of the pathname and returns a pointer to + * it. * */ -static char *BaseName (const char *pathname) +static const char *BaseName(const char *pathname) { register const char *base; - base = strrchr (pathname, FN_LIBCHAR); + base= strrchr(pathname, FN_LIBCHAR); if (base++ == NullS) - base = pathname; - return ((char*) base); + base= pathname; + return base; } /* * FUNCTION * - * Writable test to see if a pathname is writable/creatable + * Writable test to see if a pathname is writable/creatable * * SYNOPSIS * - * static BOOLEAN Writable (pathname) - * char *pathname; + * static BOOLEAN Writable(pathname) + * char *pathname; * * DESCRIPTION * - * Because the debugger might be linked in with a program that - * runs with the set-uid-bit (suid) set, we have to be careful - * about opening a user named file for debug output. This consists - * of checking the file for write access with the real user id, - * or checking the directory where the file will be created. + * Because the debugger might be linked in with a program that + * runs with the set-uid-bit (suid) set, we have to be careful + * about opening a user named file for debug output. This consists + * of checking the file for write access with the real user id, + * or checking the directory where the file will be created. * - * Returns TRUE if the user would normally be allowed write or - * create access to the named file. Returns FALSE otherwise. + * Returns TRUE if the user would normally be allowed write or + * create access to the named file. Returns FALSE otherwise. * */ #ifndef Writable -static BOOLEAN Writable ( -char *pathname) +static BOOLEAN Writable(char *pathname) { REGISTER BOOLEAN granted; REGISTER char *lastslash; - granted = FALSE; - if (EXISTS (pathname)) { - if (WRITABLE (pathname)) { - granted = TRUE; - } - } else { - lastslash = strrchr (pathname, '/'); - if (lastslash != NULL) { - *lastslash = EOS; - } else { - pathname = "."; - } - if (WRITABLE (pathname)) { - granted = TRUE; - } - if (lastslash != NULL) { - *lastslash = '/'; - } + granted= FALSE; + if (EXISTS(pathname)) + { + if (WRITABLE(pathname)) + granted= TRUE; } - return (granted); + else + { + lastslash= strrchr(pathname, '/'); + if (lastslash != NULL) + *lastslash= '\0'; + else + pathname= "."; + if (WRITABLE(pathname)) + granted= TRUE; + if (lastslash != NULL) + *lastslash= '/'; + } + return granted; } #endif @@ -1789,35 +1997,34 @@ char *pathname) /* * FUNCTION * - * ChangeOwner change owner to real user for suid programs + * ChangeOwner change owner to real user for suid programs * * SYNOPSIS * - * static VOID ChangeOwner (pathname) + * static VOID ChangeOwner(pathname) * * DESCRIPTION * - * For unix systems, change the owner of the newly created debug - * file to the real owner. This is strictly for the benefit of - * programs that are running with the set-user-id bit set. + * For unix systems, change the owner of the newly created debug + * file to the real owner. This is strictly for the benefit of + * programs that are running with the set-user-id bit set. * - * Note that at this point, the fact that pathname represents - * a newly created file has already been established. If the - * program that the debugger is linked to is not running with - * the suid bit set, then this operation is redundant (but - * harmless). + * Note that at this point, the fact that pathname represents + * a newly created file has already been established. If the + * program that the debugger is linked to is not running with + * the suid bit set, then this operation is redundant (but + * harmless). * */ #ifndef ChangeOwner -static void ChangeOwner ( -char *pathname) +static void ChangeOwner(CODE_STATE *cs, char *pathname) { - if (chown (pathname, getuid (), getgid ()) == -1) + if (chown(pathname, getuid(), getgid()) == -1) { - (void) fprintf (stderr, ERR_CHOWN, _db_process_, pathname); - perror (""); - (void) fflush (stderr); + (void) fprintf(stderr, ERR_CHOWN, cs->process, pathname); + perror(""); + (void) fflush(stderr); } } #endif @@ -1826,205 +2033,144 @@ char *pathname) /* * FUNCTION * - * _db_setjmp_ save debugger environment + * _db_setjmp_ save debugger environment * * SYNOPSIS * - * VOID _db_setjmp_ () + * VOID _db_setjmp_() * * DESCRIPTION * - * Invoked as part of the user's DBUG_SETJMP macro to save - * the debugger environment in parallel with saving the user's - * environment. + * Invoked as part of the user's DBUG_SETJMP macro to save + * the debugger environment in parallel with saving the user's + * environment. * */ #ifdef HAVE_LONGJMP -EXPORT void _db_setjmp_ () +EXPORT void _db_setjmp_() { - CODE_STATE *state; - state=code_state(); + CODE_STATE *cs=0; + get_code_state_or_return; - state->jmplevel = state->level; - state->jmpfunc = state->func; - state->jmpfile = state->file; + cs->jmplevel= cs->level; + cs->jmpfunc= cs->func; + cs->jmpfile= cs->file; } /* * FUNCTION * - * _db_longjmp_ restore previously saved debugger environment + * _db_longjmp_ restore previously saved debugger environment * * SYNOPSIS * - * VOID _db_longjmp_ () + * VOID _db_longjmp_() * * DESCRIPTION * - * Invoked as part of the user's DBUG_LONGJMP macro to restore - * the debugger environment in parallel with restoring the user's - * previously saved environment. + * Invoked as part of the user's DBUG_LONGJMP macro to restore + * the debugger environment in parallel with restoring the user's + * previously saved environment. * */ -EXPORT void _db_longjmp_ () +EXPORT void _db_longjmp_() { - CODE_STATE *state; - state=code_state(); + CODE_STATE *cs=0; + get_code_state_or_return; - state->level = state->jmplevel; - if (state->jmpfunc) { - state->func = state->jmpfunc; - } - if (state->jmpfile) { - state->file = state->jmpfile; - } + cs->level= cs->jmplevel; + if (cs->jmpfunc) + cs->func= cs->jmpfunc; + if (cs->jmpfile) + cs->file= cs->jmpfile; } #endif /* * FUNCTION * - * DelayArg convert D flag argument to appropriate value + * perror perror simulation for systems that don't have it * * SYNOPSIS * - * static int DelayArg (value) - * int value; + * static VOID perror(s) + * char *s; * * DESCRIPTION * - * Converts delay argument, given in tenths of a second, to the - * appropriate numerical argument used by the system to delay - * that that many tenths of a second. For example, on the - * amiga, there is a system call "Delay()" which takes an - * argument in ticks (50 per second). On unix, the sleep - * command takes seconds. Thus a value of "10", for one - * second of delay, gets converted to 50 on the amiga, and 1 - * on unix. Other systems will need to use a timing loop. + * Perror produces a message on the standard error stream which + * provides more information about the library or system error + * just encountered. The argument string s is printed, followed + * by a ':', a blank, and then a message and a newline. * - */ - -#ifdef AMIGA -#define HZ (50) /* Probably in some header somewhere */ -#endif - -static int DelayArg ( -int value) -{ - uint delayarg = 0; - -#if (unix || xenix) - delayarg = value / 10; /* Delay is in seconds for sleep () */ -#endif -#ifdef AMIGA - delayarg = (HZ * value) / 10; /* Delay in ticks for Delay () */ -#endif - return (delayarg); -} - - -/* - * A dummy delay stub for systems that do not support delays. - * With a little work, this can be turned into a timing loop. - */ - -#if ! defined(Delay) && ! defined(AMIGA) -static int Delay ( -int ticks) -{ - return ticks; -} -#endif - - -/* - * FUNCTION + * An undocumented feature of the unix perror is that if the string + * 's' is a null string (NOT a NULL pointer!), then the ':' and + * blank are not printed. * - * perror perror simulation for systems that don't have it - * - * SYNOPSIS - * - * static VOID perror (s) - * char *s; - * - * DESCRIPTION - * - * Perror produces a message on the standard error stream which - * provides more information about the library or system error - * just encountered. The argument string s is printed, followed - * by a ':', a blank, and then a message and a newline. - * - * An undocumented feature of the unix perror is that if the string - * 's' is a null string (NOT a NULL pointer!), then the ':' and - * blank are not printed. - * - * This version just complains about an "unknown system error". + * This version just complains about an "unknown system error". * */ #ifndef HAVE_PERROR -static void perror (s) +static void perror(s) char *s; { - if (s && *s != EOS) { - (void) fprintf (stderr, "%s: ", s); - } - (void) fprintf (stderr, "\n"); + if (s && *s != '\0') + (void) fprintf(stderr, "%s: ", s); + (void) fprintf(stderr, "\n"); } #endif /* HAVE_PERROR */ - /* flush dbug-stream, free mutex lock & wait delay */ - /* This is because some systems (MSDOS!!) dosn't flush fileheader */ - /* and dbug-file isn't readable after a system crash !! */ + /* flush dbug-stream, free mutex lock & wait delay */ + /* This is because some systems (MSDOS!!) dosn't flush fileheader */ + /* and dbug-file isn't readable after a system crash !! */ -static void dbug_flush(CODE_STATE *state) +static void dbug_flush(CODE_STATE *cs) { #ifndef THREAD - if (stack->flags & FLUSH_ON_WRITE) + if (cs->stack->flags & FLUSH_ON_WRITE) #endif { #if defined(MSDOS) || defined(__WIN__) - if (_db_fp_ != stdout && _db_fp_ != stderr) + if (cs->stack->out_file != stdout && cs->stack->out_file != stderr) { - if (!(freopen(stack->name,"a",_db_fp_))) + if (!(freopen(cs->stack->name,"a",cs->stack->out_file))) { - (void) fprintf(stderr, ERR_OPEN, _db_process_, stack->name); - fflush(stderr); - _db_fp_ = stdout; - stack -> out_file = _db_fp_; - stack -> flags|=FLUSH_ON_WRITE; + (void) fprintf(stderr, ERR_OPEN, cs->process, cs->stack->name); + fflush(stderr); + cs->stack->out_file= stderr; } } else #endif { - (void) fflush (_db_fp_); - if (stack->delay) - (void) Delay (stack->delay); + (void) fflush(cs->stack->out_file); + if (cs->stack->delay) + (void) Delay(cs->stack->delay); } } - if (!state || !state->locked) + if (!cs->locked) pthread_mutex_unlock(&THR_LOCK_dbug); } /* dbug_flush */ -void _db_lock_file() +void _db_lock_file_() { - CODE_STATE *state; - state=code_state(); + CODE_STATE *cs=0; + get_code_state_or_return; pthread_mutex_lock(&THR_LOCK_dbug); - state->locked=1; + cs->locked=1; } -void _db_unlock_file() +void _db_unlock_file_() { - CODE_STATE *state; - state=code_state(); - state->locked=0; + CODE_STATE *cs=0; + get_code_state_or_return; + cs->locked=0; pthread_mutex_unlock(&THR_LOCK_dbug); } @@ -2046,12 +2192,12 @@ void _db_unlock_file() * far. */ -static unsigned long Clock () +static unsigned long Clock() { struct rusage ru; - (void) getrusage (RUSAGE_SELF, &ru); - return ((ru.ru_utime.tv_sec * 1000) + (ru.ru_utime.tv_usec / 1000)); + (void) getrusage(RUSAGE_SELF, &ru); + return ru.ru_utime.tv_sec*1000 + ru.ru_utime.tv_usec/1000; } #elif defined(MSDOS) || defined(__WIN__) || defined(OS2) @@ -2060,43 +2206,45 @@ static ulong Clock() { return clock()*(1000/CLOCKS_PER_SEC); } -#elif defined (amiga) +#elif defined(amiga) -struct DateStamp { /* Yes, this is a hack, but doing it right */ - long ds_Days; /* is incredibly ugly without splitting this */ - long ds_Minute; /* off into a separate file */ - long ds_Tick; +struct DateStamp { /* Yes, this is a hack, but doing it right */ + long ds_Days; /* is incredibly ugly without splitting this */ + long ds_Minute; /* off into a separate file */ + long ds_Tick; }; -static int first_clock = TRUE; +static int first_clock= TRUE; static struct DateStamp begin; static struct DateStamp elapsed; -static unsigned long Clock () +static unsigned long Clock() { register struct DateStamp *now; - register unsigned long millisec = 0; - extern VOID *AllocMem (); + register unsigned long millisec= 0; + extern VOID *AllocMem(); - now = (struct DateStamp *) AllocMem ((long) sizeof (struct DateStamp), 0L); - if (now != NULL) { - if (first_clock == TRUE) { - first_clock = FALSE; - (void) DateStamp (now); - begin = *now; - } - (void) DateStamp (now); - millisec = 24 * 3600 * (1000 / HZ) * (now -> ds_Days - begin.ds_Days); - millisec += 60 * (1000 / HZ) * (now -> ds_Minute - begin.ds_Minute); - millisec += (1000 / HZ) * (now -> ds_Tick - begin.ds_Tick); - (void) FreeMem (now, (long) sizeof (struct DateStamp)); + now= (struct DateStamp *) AllocMem((long) sizeof(struct DateStamp), 0L); + if (now != NULL) + { + if (first_clock == TRUE) + { + first_clock= FALSE; + (void) DateStamp(now); + begin= *now; + } + (void) DateStamp(now); + millisec= 24 * 3600 * (1000 / HZ) * (now->ds_Days - begin.ds_Days); + millisec += 60 * (1000 / HZ) * (now->ds_Minute - begin.ds_Minute); + millisec += (1000 / HZ) * (now->ds_Tick - begin.ds_Tick); + (void) FreeMem(now, (long) sizeof(struct DateStamp)); } - return (millisec); + return millisec; } #else -static unsigned long Clock () +static unsigned long Clock() { - return (0); + return 0; } #endif /* RUSAGE */ #endif /* THREADS */ @@ -2104,11 +2252,11 @@ static unsigned long Clock () #ifdef NO_VARARGS /* - * Fake vfprintf for systems that don't support it. If this - * doesn't work, you are probably SOL... + * Fake vfprintf for systems that don't support it. If this + * doesn't work, you are probably SOL... */ -static int vfprintf (stream, format, ap) +static int vfprintf(stream, format, ap) FILE *stream; char *format; va_list ap; @@ -2116,18 +2264,18 @@ va_list ap; int rtnval; ARGS_DCL; - ARG0 = va_arg (ap, ARGS_TYPE); - ARG1 = va_arg (ap, ARGS_TYPE); - ARG2 = va_arg (ap, ARGS_TYPE); - ARG3 = va_arg (ap, ARGS_TYPE); - ARG4 = va_arg (ap, ARGS_TYPE); - ARG5 = va_arg (ap, ARGS_TYPE); - ARG6 = va_arg (ap, ARGS_TYPE); - ARG7 = va_arg (ap, ARGS_TYPE); - ARG8 = va_arg (ap, ARGS_TYPE); - ARG9 = va_arg (ap, ARGS_TYPE); - rtnval = fprintf (stream, format, ARGS_LIST); - return (rtnval); + ARG0= va_arg(ap, ARGS_TYPE); + ARG1= va_arg(ap, ARGS_TYPE); + ARG2= va_arg(ap, ARGS_TYPE); + ARG3= va_arg(ap, ARGS_TYPE); + ARG4= va_arg(ap, ARGS_TYPE); + ARG5= va_arg(ap, ARGS_TYPE); + ARG6= va_arg(ap, ARGS_TYPE); + ARG7= va_arg(ap, ARGS_TYPE); + ARG8= va_arg(ap, ARGS_TYPE); + ARG9= va_arg(ap, ARGS_TYPE); + rtnval= fprintf(stream, format, ARGS_LIST); + return rtnval; } -#endif /* NO_VARARGS */ +#endif /* NO_VARARGS */ diff --git a/dbug/monty.doc b/dbug/monty.doc index bd4096951d2..1af67b81d42 100644 --- a/dbug/monty.doc +++ b/dbug/monty.doc @@ -1,15 +1,3 @@ -Some extra options to DBUG_PUSH: - -O,logfile - As in "o,logfile", but do a close and reopen each time anything - is written to the logfile. This is needed when one expects - the program to crash anywhere, in which case one doesn't - (at least in MSDOS) get a full log-file. - -If one wants a logfile with a ':' in the filename, one can get it by -giving a double ':'. (As in "O,c::\tmp\log") - -DBUG_DUMP("keyword",memory-position,length) writes a hexdump of the -given memory-area to the outputfile. All changes that I or other people at MySQL AB have done to all files in the dbug library (Mainly in dbug.c, dbug_analyze.c, dbug_long.h, @@ -18,3 +6,4 @@ dbug.h) are put in public domain, as the rest of the dbug.c library) To my knowledge, all code in dbug library is in public domain. Michael Widenius + diff --git a/dbug/readme.prof b/dbug/readme.prof deleted file mode 100644 index cfffe376857..00000000000 --- a/dbug/readme.prof +++ /dev/null @@ -1,70 +0,0 @@ -Hi, - -I'm sending you the modifications I made to your Dbug routines to -allow profiling in a (relatively) machine independent fashion. -I use your Dbug routines fairly extensively. Unfortunately, it's -a royal pain to have to keep profiled versions of various libraries -around. The modifications allow profiling without the need for this. - -How it works. ------------- - -Basically, I just added code in the dbug routines to write out a file -called dbugmon.out (by default). This is an ascii file containing lines -of the form: - - E - X - -A second program (analyze) reads this file, and produces a report on -standard output. - -Profiling is enabled through the `g' flag. It can take a list of -procedure names for which profiling is enabled. By default, it -profiles all procedures. - -The code in ``dbug.c'' opens the profile file for appending. This -is in order that one can run a program several times, and get the -sum total of all the times, etc. - -The only system dependent part that I'm aware of is the routine -Clock() at the end of dbug.c. This returns the elapsed user time -in milliseconds. The version which I have is for 4.3 BSD. As I -don't have access to other systems, I'm not certain how this would -change. - -An example of the report generated follows: - - Profile of Execution - Execution times are in milliseconds - - Calls Time - ----- ---- - Times Percentage Time Spent Percentage -Function Called of total in Function of total Importance -======== ====== ========== =========== ========== ========== -factorial 5 83.33 30 100.00 8333 -main 1 16.67 0 0.00 0 -======== ====== ========== =========== ========== -Totals 6 100.00 30 100.00 - - -As you can see, it's quite self-evident. The ``Importance'' column is a -metric obtained by multiplying the percentage of the calls and the percentage -of the time. Functions with higher 'importance' benefit the most from -being sped up. - -I'm really not certain how to add support for setjmp/longjmp, or for -child processes, so I've ignored that for the time being. In most of -the code that I write, it isn't necessary. If you have any good ideas, -feel free to add them. - -This has been very useful to me. If you can use it as part of your -dbug distribution, please feel free to do so. - -Regards, - - Binayak Banerjee - {allegra | astrovax | bpa | burdvax}!sjuvax!bbanerje - bbanerje%sjuvax.sju.edu@relay.cs.net - July 9, 1987 diff --git a/dbug/user.r b/dbug/user.r index 198f88cf272..3bcc0c91d1d 100644 --- a/dbug/user.r +++ b/dbug/user.r @@ -672,52 +672,26 @@ from the standard include directory. .SP 2 .BL 20 .LI DBUG_ENTER\ -Used to tell the runtime support module the name of the function -being entered. -The argument must be of type "pointer to character". -The -DBUG_ENTER -macro must precede all executable lines in the -function just entered, and must come after all local declarations. -Each -DBUG_ENTER -macro must have a matching -DBUG_RETURN -or -DBUG_VOID_RETURN -macro -at the function exit points. -DBUG_ENTER -macros used without a matching -DBUG_RETURN -or -DBUG_VOID_RETURN -macro -will cause warning messages from the +Used to tell the runtime support module the name of the function being +entered. The argument must be of type "pointer to character". The +DBUG_ENTER macro must precede all executable lines in the function +just entered, and must come after all local declarations. Each +DBUG_ENTER macro must have a matching DBUG_RETURN or DBUG_VOID_RETURN +macro at the function exit points. DBUG_ENTER macros used without a +matching DBUG_RETURN or DBUG_VOID_RETURN macro will cause warning +messages from the .I dbug package runtime support module. .SP 1 EX:\ \fCDBUG_ENTER\ ("main");\fR .SP 1 .LI DBUG_RETURN\ -Used at each exit point of a function containing a -DBUG_ENTER -macro -at the entry point. -The argument is the value to return. -Functions which return no value (void) should use the -DBUG_VOID_RETURN -macro. -It -is an error to have a -DBUG_RETURN -or -DBUG_VOID_RETURN -macro in a function -which has no matching -DBUG_ENTER -macro, and the compiler will complain -if the macros are actually used (expanded). +Used at each exit point of a function containing a DBUG_ENTER macro at +the entry point. The argument is the value to return. Functions +which return no value (void) should use the DBUG_VOID_RETURN macro. +It is an error to have a DBUG_RETURN or DBUG_VOID_RETURN macro in a +function which has no matching DBUG_ENTER macro, and the compiler will +complain if the macros are actually used (expanded). .SP 1 EX:\ \fCDBUG_RETURN\ (value);\fR .br @@ -727,24 +701,20 @@ EX:\ \fCDBUG_VOID_RETURN;\fR Used to name the current process being executed. A typical argument for this macro is "argv[0]", though it will be perfectly happy with any other string. +Im multi-threaded environment threads may have different names. .SP 1 EX:\ \fCDBUG_PROCESS\ (argv[0]);\fR .SP 1 .LI DBUG_PUSH\ Sets a new debugger state by pushing the current .B dbug -state onto an -internal stack and setting up the new state using the debug control -string passed as the macro argument. -The most common usage is to set the state specified by a debug -control string retrieved from the argument list. -Note that the leading "-#" in a debug control string specified -as a command line argument must -.B not -be passed as part of the macro argument. -The proper usage is to pass a pointer to the first character -.B after -the "-#" string. +state onto an internal stack and setting up the new state using the +debug control string passed as the macro argument. The most common +usage is to set the state specified by a debug control string +retrieved from the argument list. If the control string is +.I incremental, +the new state is a copy of the old state, modified by the control +string. .SP 1 EX:\ \fCDBUG_PUSH\ (\&(argv[i][2]));\fR .br @@ -755,32 +725,37 @@ EX:\ \fCDBUG_PUSH\ ("");\fR .LI DBUG_POP\ Restores the previous debugger state by popping the state stack. Attempting to pop more states than pushed will be ignored and no -warning will be given. -The -DBUG_POP -macro has no arguments. +warning will be given. The DBUG_POP macro has no arguments. .SP 1 EX:\ \fCDBUG_POP\ ();\fR .SP 1 +.LI DBUG_SET\ +Modifies the current debugger state on top of the stack using the +debug control string passed as the macro argument. Unless +.I incremental +control string is used (see below), it's equivalent to a combination of +DBUG_POP and DBUG_PUSH. +.SP 1 +EX:\ \fCDBUG_SET\ ("d:t");\fR +.br +EX:\ \fCDBUG_SET\ ("+d,info");\fR +.br +EX:\ \fCDBUG_SET\ ("+t:-d");\fR +.SP 1 .LI DBUG_FILE\ -The -DBUG_FILE -macro is used to do explicit I/O on the debug output -stream. -It is used in the same manner as the symbols "stdout" and "stderr" -in the standard I/O package. +The DBUG_FILE macro is used to do explicit I/O on the debug output +stream. It is used in the same manner as the symbols "stdout" and +"stderr" in the standard I/O package. .SP 1 EX:\ \fCfprintf\ (DBUG_FILE,\ "Doing\ my\ own\ I/O!\\n");\fR .SP 1 .LI DBUG_EXECUTE\ -The DBUG_EXECUTE macro is used to execute any arbitrary C code. -The first argument is the debug keyword, used to trigger execution -of the code specified as the second argument. -This macro must be used cautiously because, like the -DBUG_PRINT -macro, -it is automatically selected by default whenever the 'd' flag has -no argument list (i.e., a "-#d:t" control string). +The DBUG_EXECUTE macro is used to execute any arbitrary C code. The +first argument is the debug keyword, used to trigger execution of the +code specified as the second argument. This macro must be used +cautiously because, like the DBUG_PRINT macro, it is automatically +selected by default whenever the 'd' flag has no argument list (i.e., +a "-#d:t" control string). .SP 1 EX:\ \fCDBUG_EXECUTE\ ("status",\ print_status\ ());\fR .SP 1 @@ -794,17 +769,40 @@ artificial delay checking for race conditions. .SP 1 EX:\ \fCDBUG_EXECUTE_IF\ ("crashme",\ abort\ ());\fR .SP 1 -.LI DBUG_N\ -These macros, where N is in the range 2-5, are currently obsolete -and will be removed in a future release. -Use the new DBUG_PRINT macro. +.LI DBUG_EVALUATE\ +The DBUG_EVALUATE macro is similar to DBUG_EXECUTE, but it can be used in +the expression context. The first argument is the debug keyword that is used to +choose whether the second (keyword is enabled) or the third (keyword is not +enabled) argument is evaluated. When +.B dbug +is compiled off, the third argument is evaluated. +.SP 1 +EX:\fC +.br + printf("Info-debug is %s", +.br + DBUG_EVALUATE\ ("info", "ON", "OFF"));\fR +.SP 1 +.LI DBUG_EVALUATE_IF\ +Works like DBUG_EVALUATE macro, but the second argument is +.B not +evaluated, if the keyword is not explicitly listed in +the 'd' flag. Like DBUG_EXECUTE_IF this could be used to conditionally execute +"dangerous" actions. +.SP 1 +EX:\fC +.br + if (prepare_transaction () || +.br + DBUG_EVALUATE ("crashme", (abort (), 0), 0) || +.br + commit_transaction () )\fR +.SP 1 .LI DBUG_PRINT\ -Used to do printing via the "fprintf" library function on the -current debug stream, -DBUG_FILE. -The first argument is a debug keyword, the second is a format string -and the corresponding argument list. -Note that the format string and argument list are all one macro argument +Used to do printing via the "fprintf" library function on the current +debug stream, DBUG_FILE. The first argument is a debug keyword, the +second is a format string and the corresponding argument list. Note +that the format string and argument list are all one macro argument and .B must be enclosed in parentheses. @@ -816,10 +814,10 @@ EX:\ \fCDBUG_PRINT\ ("type",\ ("type\ is\ %x", type));\fR EX:\ \fCDBUG_PRINT\ ("stp",\ ("%x\ ->\ %s", stp, stp\ ->\ name));\fR .SP 1 .LI DBUG_DUMP\ -Used to dump a memory block in hex via the "fprintf" library function on the -current debug stream, DBUG_FILE. -The first argument is a debug keyword, the second is a pointer to -a memory to dump, the third is a number of bytes to dump. +Used to dump a memory block in hex via the "fprintf" library function +on the current debug stream, DBUG_FILE. The first argument is a debug +keyword, the second is a pointer to a memory to dump, the third is a +number of bytes to dump. .SP 1 EX: \fCDBUG_DBUG\ ("net",\ packet,\ len);\fR .SP 1 @@ -875,13 +873,28 @@ library. So there will be no need to disable asserts separately with NDEBUG. .SP 1 EX:\ \fCDBUG_ASSERT(\ a\ >\ 0\ );\fR .SP 1 -.LI DBUG_OUTPUT\ -In multi-threaded environment disables (or enables) any -.I dbug -output from the current thread. +.LI DBUG_EXPLAIN\ +Generates control string corresponding to the current debug state. +The macro takes two arguments - a buffer to store the result string +into and its length. The macro (which could be used as a function) +returns 1 if the control string didn't fit into the buffer and was +truncated and 0 otherwise. .SP 1 -EX:\ \fCDBUG_OUTPUT(\ 0\ );\fR +EX:\fC +.br + char buf[256]; +.br + DBUG_EXPLAIN( buf, sizeof(buf) );\fR .SP 1 +.LI DBUG_SET_INITIAL\ +.LI DBUG_EXPLAIN_INITIAL\ +.br +These two macros are identical to DBUG_SET and DBUG_EXPLAIN, but they +operate on the debug state that any new thread starts from. +Modifying +.I initial +value does not affect threads that are already running. Obviously, +these macros are only useful in the multi-threaded environment. .LE .SK @@ -893,42 +906,52 @@ DEBUG CONTROL STRING The debug control string is used to set the state of the debugger via the .B DBUG_PUSH -macro. -This section summarizes the currently available debugger options -and the flag characters which enable or disable them. -Argument lists enclosed in '[' and ']' are optional. +or +.B DBUG_SET +macros. Control string consists of colon separate flags. A flag +may take an argument or a list of arguments. If a control string +starts from a '+' sign it works +.I incrementally, +that is, it can modify existing state without overriding it. In such a +string every flag may be preceded by a '+' or '-' to enable or disable +a corresponding option in the debugger state. This section summarizes +the currently available debugger options and the flag characters which +enable or disable them. Argument lists enclosed in '[' and ']' are +optional. .SP 2 .BL 22 .LI a[,file] -Redirect the debugger output stream and append it to the specified file. -The default output stream is stderr. -A null argument list causes output to be redirected to stdout. -Double the colon, if you want it in the path +Redirect the debugger output stream and append it to the specified +file. The default output stream is stderr. A null argument list +causes output to be redirected to stdout. A colon that is followed by +the '\\' or '/' is cosidered a part of the path and not a flag +separator. .SP 1 -EX: \fCa,C::\\tmp\\log\fR +EX: \fCa,C:\\tmp\\log\fR .LI A[,file] Like 'a[,file]' but ensure that data are written after each write (this typically implies flush or close/reopen). It helps to get -a complete log file in case of crashes. This mode is implied in +a complete log file in case of crashes. This mode is implicit in multi-threaded environment. .LI d[,keywords] Enable output from macros with specified keywords. -A null list of keywords implies that all keywords are selected. +An empty list of keywords implies that all keywords are selected. .LI D[,time] Delay for specified time after each output line, to let output drain. Time is given in tenths of a second (value of 10 is one second). Default is zero. .LI f[,functions] Limit debugger actions to the specified list of functions. -A null list of functions implies that all functions are selected. +An empty list of functions implies that all functions are selected. .LI F Mark each debugger output line with the name of the source file containing the macro causing the output. .LI i -Mark each debugger output line with the PID of the current process. +Mark each debugger output line with the PID (or thread ID) of the +current process. .LI g,[functions] Enable profiling for the specified list of functions. -By default profiling is enabled for all functions. +An empty list of functions enables profiling for all functions. See .B PROFILING\ WITH\ DBUG below. @@ -946,20 +969,18 @@ Like 'a[,file]' but overwrite old file, do not append. .LI O[,file] Like 'A[,file]' but overwrite old file, do not append. .LI p[,processes] -Limit debugger actions to the specified processes. -A null list implies all processes. -This is useful for processes which run child processes. -Note that each debugger output line can be marked with the name of -the current process via the 'P' flag. -The process name must match the argument passed to the +Limit debugger actions to the specified processes. An empty list +implies all processes. This is useful for processes which run child +processes. Note that each debugger output line can be marked with the +name of the current process via the 'P' flag. The process name must +match the argument passed to the .B DBUG_PROCESS macro. .LI P Mark each debugger output line with the name of the current process. Most useful when used with a process which runs child processes that -are also being debugged. -Note that the parent process must arrange for the debugger control -string to be passed to the child processes. +are also being debugged. Note that the parent process must arrange +for the debugger control string to be passed to the child processes. .LI r Used in conjunction with the .B DBUG_PUSH @@ -981,7 +1002,59 @@ and Enable function control flow tracing. The maximum nesting depth is specified by N, and defaults to 200. +.LI T +Mark each debugger output line with the current timestamp. +The value is printed with microsecond resolution, as returned by +.I gettimeofday() +system call. The actual resolution is OS- and hardware-dependent. .LE + +.SK +.B +MULTI-THREADED DEBUGGING +.R + +.P +When +.I dbug +is used in a multi-threaded environment there are few differences from a single-threaded +case to keep in mind. This section tries to summarize them. +.SP 2 +.BL 5 +.LI +Every thread has its own stack of debugger states. +.B DBUG_PUSH +and +.B DBUG_POP +affect only the thread that executed them. +.LI +At the bottom of the stack for all threads there is the common +.I initial +state. Changes to this state (for example, with +.B DBUG_SET_INITIAL +macro) affect all new threads and all running threads that didn't +.B DBUG_PUSH +yet. +.LI +Every thread can have its own name, that can be set with +.B DBUG_PROCESS +macro. Thus, "-#p,name1,name2" can be used to limit the output to specific threads. +.LI +When printing directly to +.B DBUG_FILE +it may be necessary to prevent other threads from writing something between two parts +of logically indivisible output. It is done with +.B DBUG_LOCK_FILE +and +.B DBUG_UNLOCK_FILE +macors. See the appropriate section for examples. +.LI +"-#o,file" and "-#O,file" are treated as "-#a,file" and "-#A,file" respectively. That is +all writes to a file are always followed by a flush. +.LI +"-#i" prints not a PID but a thread id in the form of "T@nnn" +.LE + .SK .B PROFILING WITH DBUG diff --git a/include/my_dbug.h b/include/my_dbug.h index b76a3fcc8c9..db2139fa2e2 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -21,15 +21,18 @@ extern "C" { #endif #if !defined(DBUG_OFF) && !defined(_lint) -extern int _db_on_,_no_db_; -extern FILE *_db_fp_; -extern char *_db_process_; -extern int _db_keyword_(const char *keyword); +struct _db_code_state_; +extern int _db_keyword_(struct _db_code_state_ *cs, const char *keyword); extern int _db_strict_keyword_(const char *keyword); +extern int _db_explain_(struct _db_code_state_ *cs, char *buf, int len); +extern int _db_explain_init_(char *buf, int len); extern void _db_setjmp_(void); extern void _db_longjmp_(void); +extern void _db_process_(const char *name); extern void _db_push_(const char *control); extern void _db_pop_(void); +extern void _db_set_(struct _db_code_state_ *cs, const char *control); +extern void _db_set_init_(const char *control); extern void _db_enter_(const char *_func_,const char *_file_,uint _line_, const char **_sfunc_,const char **_sfile_, uint *_slevel_, char ***); @@ -39,61 +42,66 @@ extern void _db_pargs_(uint _line_,const char *keyword); 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_lock_file(void); -extern void _db_unlock_file(void); +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_) #define DBUG_LEAVE \ - (_db_return_ (__LINE__, &_db_func_, &_db_file_, &_db_level_)) -#define DBUG_RETURN(a1) {DBUG_LEAVE; return(a1);} -#define DBUG_VOID_RETURN {DBUG_LEAVE; return;} + _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) #define DBUG_EXECUTE(keyword,a1) \ - {if (_db_on_) {if (_db_keyword_ (keyword)) { a1 }}} + do {if (_db_keyword_(0, (keyword))) { a1 }} while(0) +#define DBUG_EXECUTE_IF(keyword,a1) \ + do {if (_db_strict_keyword_ (keyword)) { a1 } } while(0) +#define DBUG_EVALUATE(keyword,a1,a2) \ + (_db_keyword_(0,(keyword)) ? (a1) : (a2)) +#define DBUG_EVALUATE_IF(keyword,a1,a2) \ + (_db_strict_keyword_((keyword)) ? (a1) : (a2)) #define DBUG_PRINT(keyword,arglist) \ - {if (_db_on_) {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;}} + do {_db_pargs_(__LINE__,keyword); _db_doprnt_ arglist;} while(0) #define DBUG_PUSH(a1) _db_push_ (a1) #define DBUG_POP() _db_pop_ () -#define DBUG_PROCESS(a1) (_db_process_ = a1) -#define DBUG_FILE (_db_fp_) +#define DBUG_SET(a1) _db_set_ (0, (a1)) +#define DBUG_SET_INITIAL(a1) _db_set_init_ (a1) +#define DBUG_PROCESS(a1) _db_process_(a1) +#define DBUG_FILE _db_fp_() #define DBUG_SETJMP(a1) (_db_setjmp_ (), setjmp (a1)) #define DBUG_LONGJMP(a1,a2) (_db_longjmp_ (), longjmp (a1, a2)) -#define DBUG_DUMP(keyword,a1,a2)\ - {if (_db_on_) {_db_dump_(__LINE__,keyword,a1,a2);}} -#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_LOCK_FILE { _db_lock_file(); } -#define DBUG_UNLOCK_FILE { _db_unlock_file(); } -#define DBUG_OUTPUT(A) { _db_output_(A); } +#define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2) +#define DBUG_LOCK_FILE _db_lock_file_() +#define DBUG_UNLOCK_FILE _db_unlock_file_() #define DBUG_ASSERT(A) assert(A) -#define DBUG_EXECUTE_IF(keyword,a1) \ - {if (_db_on_) {if (_db_strict_keyword_ (keyword)) { a1 }}} +#define DBUG_EXPLAIN(buf,len) _db_explain_(0, (buf),(len)) +#define DBUG_EXPLAIN_INITIAL(buf,len) _db_explain_init_((buf),(len)) #else /* No debugger */ #define DBUG_ENTER(a1) -#define DBUG_RETURN(a1) return(a1) -#define DBUG_VOID_RETURN return -#define DBUG_EXECUTE(keyword,a1) {} -#define DBUG_EXECUTE_IF(keyword,a1) {} -#define DBUG_PRINT(keyword,arglist) {} -#define DBUG_PUSH(a1) {} -#define DBUG_POP() {} -#define DBUG_PROCESS(a1) {} -#define DBUG_FILE (stderr) -#define DBUG_SETJMP setjmp -#define DBUG_LONGJMP longjmp -#define DBUG_DUMP(keyword,a1,a2) {} -#define DBUG_IN_USE 0 -#define DEBUGGER_OFF -#define DEBUGGER_ON +#define DBUG_RETURN(a1) do { return(a1); } while(0) +#define DBUG_VOID_RETURN do { return; } while(0) +#define DBUG_EXECUTE(keyword,a1) do { } while(0) +#define DBUG_EXECUTE_IF(keyword,a1) do { } while(0) +#define DBUG_EVALUATE(keyword,a1,a2) (a2) +#define DBUG_EVALUATE_IF(keyword,a1,a2) (a2) +#define DBUG_PRINT(keyword,arglist) do { } while(0) +#define DBUG_PUSH(a1) +#define DBUG_SET(a1) +#define DBUG_SET_INITIAL(a1) +#define DBUG_POP() +#define DBUG_PROCESS(a1) (a1) +#define DBUG_SETJMP(a1) setjmp(a1) +#define DBUG_LONGJMP(a1) longjmp(a1) +#define DBUG_DUMP(keyword,a1,a2) +#define DBUG_ASSERT(A) #define DBUG_LOCK_FILE +#define DBUG_FILE (stderr) #define DBUG_UNLOCK_FILE -#define DBUG_OUTPUT(A) -#define DBUG_ASSERT(A) {} +#define DBUG_EXPLAIN(buf,len) +#define DBUG_EXPLAIN_INITIAL(buf,len) #endif #ifdef __cplusplus } diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index a77d1408383..63347713288 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -179,10 +179,8 @@ void STDCALL mysql_server_end() if (!org_my_init_done) { my_end(0); -#ifndef THREAD /* Remove TRACING, if enabled by mysql_debug() */ DBUG_POP(); -#endif } else mysql_thread_end(); @@ -267,16 +265,12 @@ mysql_debug(const char *debug __attribute__((unused))) { #ifndef DBUG_OFF char *env; - if (_db_on_) - return; /* Already using debugging */ if (debug) { - DEBUGGER_ON; DBUG_PUSH(debug); } else if ((env = getenv("MYSQL_DEBUG"))) { - DEBUGGER_ON; DBUG_PUSH(env); #if !defined(_WINVER) && !defined(WINVER) puts("\n-------------------------------------------------------"); diff --git a/mysys/my_init.c b/mysys/my_init.c index f28f47e090e..d4d7a26ebaa 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -213,6 +213,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", WSACleanup(); #endif /* __WIN__ */ my_init_done=0; + DBUG_VOID_RETURN; } /* my_end */ diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 4d23d01cd82..d93f45091c6 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -282,7 +282,7 @@ const char *my_thread_name(void) if (!tmp->name[0]) { long id=my_thread_id(); - sprintf(name_buff,"T@%ld", id); + sprintf(name_buff,"T@%lu", id); strmake(tmp->name,name_buff,THREAD_NAME_SIZE); } return tmp->name; diff --git a/mysys/testhash.c b/mysys/testhash.c index d15016113cd..a0bc6685d61 100644 --- a/mysys/testhash.c +++ b/mysys/testhash.c @@ -250,7 +250,6 @@ err: static int get_options(int argc, char **argv) { char *pos,*progname; - DEBUGGER_OFF; progname= argv[0]; @@ -270,7 +269,6 @@ static int get_options(int argc, char **argv) printf("Usage: %s [-?ABIKLWv] [-m#] [-t#]\n",progname); exit(0); case '#': - DEBUGGER_ON; DBUG_PUSH (++pos); break; } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index cc40ca0b92b..32b67cd23e5 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -116,7 +116,7 @@ int ha_myisammrg::open(const char *name, int mode, uint test_if_locked) DBUG_PRINT("info", ("ha_myisammrg::open exit %d", my_errno)); return (my_errno ? my_errno : -1); } - DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc...")) + DBUG_PRINT("info", ("ha_myisammrg::open myrg_extrafunc...")); myrg_extrafunc(file, query_cache_invalidate_by_MyISAM_filename_ref); if (!(test_if_locked == HA_OPEN_WAIT_IF_LOCKED || test_if_locked == HA_OPEN_ABORT_IF_LOCKED)) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 361401e22d6..69b4675c290 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2773,7 +2773,7 @@ void ndb_unpack_record(TABLE *table, NdbValue *value, ndb_blob->getDefined(isNull); if (isNull == 1) { - DBUG_PRINT("info",("[%u] NULL", col_no)) + DBUG_PRINT("info",("[%u] NULL", col_no)); field->set_null(row_offset); } else if (isNull == -1) @@ -2811,15 +2811,18 @@ void ha_ndbcluster::unpack_record(byte *buf) const NDBCOL *hidden_col= tab->getColumn(hidden_no); const NdbRecAttr* rec= m_value[hidden_no].rec; DBUG_ASSERT(rec); - DBUG_PRINT("hidden", ("%d: %s \"%llu\"", hidden_no, + DBUG_PRINT("hidden", ("%d: %s \"%llu\"", hidden_no, hidden_col->getName(), rec->u_64_value())); - } - //print_results(); + } + //DBUG_EXECUTE("value", print_results();); #endif } /* Utility function to print/dump the fetched field + to avoid unnecessary work, wrap in DBUG_EXECUTE as in: + + DBUG_EXECUTE("value", print_results();); */ void ha_ndbcluster::print_results() @@ -2827,8 +2830,6 @@ void ha_ndbcluster::print_results() DBUG_ENTER("print_results"); #ifndef DBUG_OFF - if (!_db_on_) - DBUG_VOID_RETURN; char buf_type[MAX_FIELD_WIDTH], buf_val[MAX_FIELD_WIDTH]; String type(buf_type, sizeof(buf_type), &my_charset_bin); @@ -6413,7 +6414,7 @@ ha_ndbcluster::register_query_cache_table(THD *thd, if (!is_autocommit) { - DBUG_PRINT("exit", ("Can't register table during transaction")) + DBUG_PRINT("exit", ("Can't register table during transaction")); DBUG_RETURN(FALSE); } @@ -6421,7 +6422,7 @@ ha_ndbcluster::register_query_cache_table(THD *thd, if (ndb_get_commitcount(thd, m_dbname, m_tabname, &commit_count)) { *engine_data= 0; - DBUG_PRINT("exit", ("Error, could not get commitcount")) + DBUG_PRINT("exit", ("Error, could not get commitcount")); DBUG_RETURN(FALSE); } *engine_data= commit_count; diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 0fa9daa66b4..1239bf50641 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -100,24 +100,21 @@ static TABLE_LIST binlog_tables; #ifndef DBUG_OFF static void print_records(TABLE *table, const char *record) { - if (_db_on_) + for (uint j= 0; j < table->s->fields; j++) { - for (uint j= 0; j < table->s->fields; j++) + char buf[40]; + int pos= 0; + Field *field= table->field[j]; + const byte* field_ptr= field->ptr - table->record[0] + record; + int pack_len= field->pack_length(); + int n= pack_len < 10 ? pack_len : 10; + + for (int i= 0; i < n && pos < 20; i++) { - char buf[40]; - int pos= 0; - Field *field= table->field[j]; - const byte* field_ptr= field->ptr - table->record[0] + record; - int pack_len= field->pack_length(); - int n= pack_len < 10 ? pack_len : 10; - - for (int i= 0; i < n && pos < 20; i++) - { - pos+= sprintf(&buf[pos]," %x", (int) (unsigned char) field_ptr[i]); - } - buf[pos]= 0; - DBUG_PRINT("info",("[%u]field_ptr[0->%d]: %s", j, n, buf)); + pos+= sprintf(&buf[pos]," %x", (int) (unsigned char) field_ptr[i]); } + buf[pos]= 0; + DBUG_PRINT("info",("[%u]field_ptr[0->%d]: %s", j, n, buf)); } } #else @@ -2483,7 +2480,7 @@ ndb_binlog_thread_handle_data_event(Ndb *ndb, NdbEventOperation *pOp, DBUG_ASSERT(ret == 0); } ndb_unpack_record(table, share->ndb_value[n], &b, table->record[n]); - print_records(table, table->record[n]); + DBUG_EXECUTE("info", print_records(table, table->record[n]);); trans.delete_row(::server_id, injector::transaction::table(table, true), &b, n_fields, table->record[n]); } @@ -2502,7 +2499,7 @@ ndb_binlog_thread_handle_data_event(Ndb *ndb, NdbEventOperation *pOp, } ndb_unpack_record(table, share->ndb_value[0], &b, table->record[0]); - print_records(table, table->record[0]); + DBUG_EXECUTE("info", print_records(table, table->record[0]);); if (table->s->primary_key != MAX_KEY) { /* @@ -2527,7 +2524,7 @@ ndb_binlog_thread_handle_data_event(Ndb *ndb, NdbEventOperation *pOp, DBUG_ASSERT(ret == 0); } ndb_unpack_record(table, share->ndb_value[1], &b, table->record[1]); - print_records(table, table->record[1]); + DBUG_EXECUTE("info", print_records(table, table->record[1]);); trans.update_row(::server_id, injector::transaction::table(table, true), &b, n_fields, diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index e2eb60892f4..2abf9984464 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -2860,7 +2860,7 @@ longlong Item_is_not_null_test::val_int() } if (args[0]->is_null()) { - DBUG_PRINT("info", ("null")) + DBUG_PRINT("info", ("null")); owner->was_null|= 1; DBUG_RETURN(0); } diff --git a/sql/lock.cc b/sql/lock.cc index 5f1141cc841..9cd0dcce610 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -622,7 +622,7 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count, table_ptr[i], count, (thd == logger.get_general_log_thd()) || (thd == logger.get_slow_log_thd()))) - return 0; + DBUG_RETURN(0); } if (!(sql_lock= (MYSQL_LOCK*) diff --git a/sql/log_event.cc b/sql/log_event.cc index 64a692d394d..2427825e646 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -5654,7 +5654,7 @@ Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid, m_data_size= TABLE_MAP_HEADER_LEN; - DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;) + DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;); m_data_size+= m_dblen + 2; // Include length and terminating \0 m_data_size+= m_tbllen + 2; // Include length and terminating \0 m_data_size+= 1 + m_colcnt; // COLCNT and column types diff --git a/sql/mysqld.cc b/sql/mysqld.cc index be476c11533..1cdb7f53096 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1089,12 +1089,8 @@ pthread_handler_t kill_server_thread(void *arg __attribute__((unused))) extern "C" sig_handler print_signal_warning(int sig) { - if (!DBUG_IN_USE) - { - if (global_system_variables.log_warnings) - sql_print_warning("Got signal %d from thread %d", - sig,my_thread_id()); - } + if (global_system_variables.log_warnings) + sql_print_warning("Got signal %d from thread %d", sig,my_thread_id()); #ifdef DONT_REMEMBER_SIGNAL my_sigset(sig,print_signal_warning); /* int. thread system calls */ #endif @@ -1717,7 +1713,7 @@ void end_thread(THD *thd, bool put_in_cache) ! abort_loop && !kill_cached_threads) { /* Don't kill the thread, just put it in cache for reuse */ - DBUG_PRINT("info", ("Adding thread to cache")) + DBUG_PRINT("info", ("Adding thread to cache")); cached_thread_count++; while (!abort_loop && ! wake_thread && ! kill_cached_threads) (void) pthread_cond_wait(&COND_thread_cache, &LOCK_thread_count); @@ -1738,13 +1734,13 @@ void end_thread(THD *thd, bool put_in_cache) } } - DBUG_PRINT("info", ("sending a broadcast")) + DBUG_PRINT("info", ("sending a broadcast")); /* Tell main we are ready */ (void) pthread_mutex_unlock(&LOCK_thread_count); /* It's safe to broadcast outside a lock (COND... is not deleted here) */ (void) pthread_cond_broadcast(&COND_thread_count); - DBUG_PRINT("info", ("unlocked thread_count mutex")) + DBUG_PRINT("info", ("unlocked thread_count mutex")); #ifdef ONE_THREAD if (!(test_flags & TEST_NO_THREADS)) // For debugging under Linux #endif @@ -3467,8 +3463,6 @@ int win_main(int argc, char **argv) int main(int argc, char **argv) #endif { - DEBUGGER_OFF; - rpl_filter= new Rpl_filter; binlog_filter= new Rpl_filter; if (!rpl_filter || !binlog_filter) @@ -7065,7 +7059,6 @@ static void mysql_init_variables(void) max_system_variables.max_join_size= (ulonglong) HA_POS_ERROR; global_system_variables.old_passwords= 0; global_system_variables.old_alter_table= 0; - /* Default behavior for 4.1 and 5.0 is to treat NULL values as unequal when collecting index statistics for MyISAM tables. @@ -7172,7 +7165,8 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), switch(optid) { case '#': #ifndef DBUG_OFF - DBUG_PUSH(argument ? argument : default_dbug_option); + DBUG_SET(argument ? argument : default_dbug_option); + DBUG_SET_INITIAL(argument ? argument : default_dbug_option); #endif opt_endinfo=1; /* unireg: memory allocation */ break; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 887690aecc1..9fe3212a0f8 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -10162,8 +10162,6 @@ static void print_sel_tree(PARAM *param, SEL_TREE *tree, key_map *tree_map, int idx; char buff[1024]; DBUG_ENTER("print_sel_tree"); - if (! _db_on_) - DBUG_VOID_RETURN; String tmp(buff,sizeof(buff),&my_charset_bin); tmp.length(0); @@ -10192,9 +10190,7 @@ static void print_ror_scans_arr(TABLE *table, const char *msg, struct st_ror_scan_info **start, struct st_ror_scan_info **end) { - DBUG_ENTER("print_ror_scans"); - if (! _db_on_) - DBUG_VOID_RETURN; + DBUG_ENTER("print_ror_scans_arr"); char buff[1024]; String tmp(buff,sizeof(buff),&my_charset_bin); @@ -10258,7 +10254,7 @@ static void print_quick(QUICK_SELECT_I *quick, const key_map *needed_reg) { char buf[MAX_KEY/8+1]; DBUG_ENTER("print_quick"); - if (! _db_on_ || !quick) + if (!quick) DBUG_VOID_RETURN; DBUG_LOCK_FILE; diff --git a/sql/set_var.cc b/sql/set_var.cc index a6c2fca7fc5..efdd44d7caa 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -205,6 +205,9 @@ sys_var_long_ptr sys_concurrent_insert("concurrent_insert", &myisam_concurrent_insert); sys_var_long_ptr sys_connect_timeout("connect_timeout", &connect_timeout); +#ifndef DBUG_OFF +sys_var_thd_dbug sys_dbug("debug"); +#endif sys_var_enum sys_delay_key_write("delay_key_write", &delay_key_write_options, &delay_key_write_typelib, @@ -722,13 +725,16 @@ SHOW_VAR init_vars[]= { {"datadir", mysql_real_data_home, SHOW_CHAR}, {sys_date_format.name, (char*) &sys_date_format, SHOW_SYS}, {sys_datetime_format.name, (char*) &sys_datetime_format, SHOW_SYS}, +#ifndef DBUG_OFF + {sys_dbug.name, (char*) &sys_dbug, SHOW_SYS}, +#endif {sys_default_week_format.name, (char*) &sys_default_week_format, SHOW_SYS}, {sys_delay_key_write.name, (char*) &sys_delay_key_write, SHOW_SYS}, {sys_delayed_insert_limit.name, (char*) &sys_delayed_insert_limit,SHOW_SYS}, {sys_delayed_insert_timeout.name, (char*) &sys_delayed_insert_timeout, SHOW_SYS}, {sys_delayed_queue_size.name,(char*) &sys_delayed_queue_size, SHOW_SYS}, {sys_div_precincrement.name,(char*) &sys_div_precincrement,SHOW_SYS}, - {sys_engine_condition_pushdown.name, + {sys_engine_condition_pushdown.name, (char*) &sys_engine_condition_pushdown, SHOW_SYS}, {sys_event_executor.name, (char*) &sys_event_executor, SHOW_SYS}, {sys_expire_logs_days.name, (char*) &sys_expire_logs_days, SHOW_SYS}, @@ -3461,6 +3467,33 @@ bool sys_var_trust_routine_creators::update(THD *thd, set_var *var) return sys_var_bool_ptr::update(thd, var); } +/* even session variable here requires SUPER, because of -#o,file */ +bool sys_var_thd_dbug::check(THD *thd, set_var *var) +{ + return check_global_access(thd, SUPER_ACL); +} + +bool sys_var_thd_dbug::update(THD *thd, set_var *var) +{ + if (var->type == OPT_GLOBAL) + DBUG_SET_INITIAL(var ? var->value->str_value.c_ptr() : ""); + else + { + DBUG_POP(); + DBUG_PUSH(var ? var->value->str_value.c_ptr() : ""); + } + return 0; +} + +byte *sys_var_thd_dbug::value_ptr(THD *thd, enum_var_type type, LEX_STRING *b) +{ + char buf[256]; + if (type == OPT_GLOBAL) + DBUG_EXPLAIN_INITIAL(buf, sizeof(buf)); + else + DBUG_EXPLAIN(buf, sizeof(buf)); + (byte*) thd->strdup(buf); +} /**************************************************************************** Used templates diff --git a/sql/set_var.h b/sql/set_var.h index 34873947483..9b640517e64 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -45,7 +45,7 @@ public: struct my_option *option_limits; /* Updated by by set_var_init() */ uint name_length; /* Updated by by set_var_init() */ const char *name; - + sys_after_update_func after_update; bool no_support_one_shot; sys_var(const char *name_arg) @@ -413,7 +413,7 @@ class sys_var_thd_bit :public sys_var_thd public: ulong bit_flag; bool reverse; - sys_var_thd_bit(const char *name_arg, + sys_var_thd_bit(const char *name_arg, sys_check_func c_func, sys_update_func u_func, ulong bit, bool reverse_arg=0) :sys_var_thd(name_arg), check_func(c_func), update_func(u_func), @@ -427,6 +427,24 @@ public: byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *base); }; +class sys_var_thd_dbug :public sys_var_thd +{ +public: + sys_var_thd_dbug(const char *name_arg) :sys_var_thd(name_arg) {} + bool check_update_type(Item_result type) { return type != STRING_RESULT; } + bool check(THD *thd, set_var *var); + SHOW_TYPE type() { return SHOW_CHAR; } + bool update(THD *thd, set_var *var); + void set_default(THD *thd, enum_var_type type) + { + char buf[256]; + DBUG_EXPLAIN_INITIAL(buf, sizeof(buf)); + DBUG_SET(buf); + } + byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *b); +}; + + /* some variables that require special handling */ diff --git a/sql/slave.cc b/sql/slave.cc index 763db31c05d..e60521af3a0 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2920,7 +2920,7 @@ static int has_temporary_error(THD *thd) MYSQL_ERROR *err; while ((err= it++)) { - DBUG_PRINT("info", ("has warning %d %s", err->code, err->msg)) + DBUG_PRINT("info", ("has warning %d %s", err->code, err->msg)); switch (err->code) { case ER_GET_TEMPORARY_ERRMSG: diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index aec370e104a..5b060aa13c6 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -316,13 +316,13 @@ TODO list: #define MUTEX_UNLOCK(M) {DBUG_PRINT("lock", ("mutex unlock 0x%lx",\ (ulong)(M))); pthread_mutex_unlock(M);} #define RW_WLOCK(M) {DBUG_PRINT("lock", ("rwlock wlock 0x%lx",(ulong)(M))); \ - if (!rw_wrlock(M)) DBUG_PRINT("lock", ("rwlock wlock ok")) \ + if (!rw_wrlock(M)) DBUG_PRINT("lock", ("rwlock wlock ok")); \ else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); } #define RW_RLOCK(M) {DBUG_PRINT("lock", ("rwlock rlock 0x%lx", (ulong)(M))); \ - if (!rw_rdlock(M)) DBUG_PRINT("lock", ("rwlock rlock ok")) \ + if (!rw_rdlock(M)) DBUG_PRINT("lock", ("rwlock rlock ok")); \ else DBUG_PRINT("lock", ("rwlock wlock FAILED %d", errno)); } #define RW_UNLOCK(M) {DBUG_PRINT("lock", ("rwlock unlock 0x%lx",(ulong)(M))); \ - if (!rw_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")) \ + if (!rw_unlock(M)) DBUG_PRINT("lock", ("rwlock unlock ok")); \ else DBUG_PRINT("lock", ("rwlock unlock FAILED %d", errno)); } #define STRUCT_LOCK(M) {DBUG_PRINT("lock", ("%d struct lock...",__LINE__)); \ pthread_mutex_lock(M);DBUG_PRINT("lock", ("struct lock OK"));} diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 9fee7abb619..ecada58dace 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -518,7 +518,7 @@ static int plugin_initialize(struct st_plugin_int *plugin) sql_print_error("Plugin '%s' init function returned error.", plugin->name.str); DBUG_PRINT("warning", ("Plugin '%s' init function returned error.", - plugin->name.str)) + plugin->name.str)); goto err; } } @@ -531,7 +531,7 @@ static int plugin_initialize(struct st_plugin_int *plugin) sql_print_error("Plugin '%s' handlerton init returned error.", plugin->name.str); DBUG_PRINT("warning", ("Plugin '%s' handlerton init returned error.", - plugin->name.str)) + plugin->name.str)); goto err; } break; @@ -580,7 +580,7 @@ static void plugin_call_deinitializer(void) if (tmp->plugin->deinit()) { DBUG_PRINT("warning", ("Plugin '%s' deinit function returned error.", - tmp->name.str)) + tmp->name.str)); } } tmp->state= PLUGIN_IS_UNINITIALIZED; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 47aa53d25e2..e4ac532d679 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -13197,7 +13197,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, for (i= 0; (item= it++); i++) { Field *field; - + if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) item_field= item; else @@ -13216,7 +13216,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, DBUG_RETURN(TRUE); // Fatal error item_field->name= item->name; #ifndef DBUG_OFF - if (_db_on_ && !item_field->name) + if (!item_field->name) { char buff[256]; String str(buff,sizeof(buff),&my_charset_bin); diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c index 2de49bcb66b..a74872dbd11 100644 --- a/storage/heap/hp_test2.c +++ b/storage/heap/hp_test2.c @@ -617,7 +617,6 @@ err: static int get_options(int argc,char *argv[]) { char *pos,*progname; - DEBUGGER_OFF; progname= argv[0]; @@ -646,7 +645,6 @@ static int get_options(int argc,char *argv[]) printf("Usage: %s [-?ABIKLsWv] [-m#] [-t#]\n",progname); exit(0); case '#': - DEBUGGER_ON; DBUG_PUSH (++pos); break; } diff --git a/storage/myisam/ft_eval.c b/storage/myisam/ft_eval.c index 34248c69f20..eab9d37af0b 100644 --- a/storage/myisam/ft_eval.c +++ b/storage/myisam/ft_eval.c @@ -170,7 +170,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'q': silent=1; break; case 'S': if (stopwordlist==ft_precompiled_stopwords) stopwordlist=NULL; break; case '#': - DEBUGGER_ON; DBUG_PUSH (argument); break; case 'V': diff --git a/storage/myisam/ft_test1.c b/storage/myisam/ft_test1.c index 14be9aa1e8c..d54b344e2cd 100644 --- a/storage/myisam/ft_test1.c +++ b/storage/myisam/ft_test1.c @@ -284,7 +284,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), case 'N': no_search=1; break; case 'S': no_stopwords=1; break; case '#': - DEBUGGER_ON; DBUG_PUSH (argument); break; case 'V': diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c index c891cce89ac..abf1d1ea9a7 100644 --- a/storage/myisam/mi_open.c +++ b/storage/myisam/mi_open.c @@ -208,9 +208,9 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags) if (len != MI_BASE_INFO_SIZE) { DBUG_PRINT("warning",("saved_base_info_length: %d base_info_length: %d", - len,MI_BASE_INFO_SIZE)) + len,MI_BASE_INFO_SIZE)); } - disk_pos= (char*) + disk_pos= (char*) my_n_base_info_read((uchar*) disk_cache + base_pos, &share->base); share->state.state_length=base_pos; diff --git a/storage/myisam/mi_test1.c b/storage/myisam/mi_test1.c index 60225ccc7f3..0e62b074376 100644 --- a/storage/myisam/mi_test1.c +++ b/storage/myisam/mi_test1.c @@ -648,7 +648,6 @@ get_one_option(int optid, const struct my_option *opt __attribute__((unused)), printf("test1 Ver 1.2 \n"); exit(0); case '#': - DEBUGGER_ON; DBUG_PUSH (argument); break; case '?': diff --git a/storage/myisam/mi_test2.c b/storage/myisam/mi_test2.c index 6a6dcb971a2..e77a37d853f 100644 --- a/storage/myisam/mi_test2.c +++ b/storage/myisam/mi_test2.c @@ -864,7 +864,6 @@ err: static void get_options(int argc, char **argv) { char *pos,*progname; - DEBUGGER_OFF; progname= argv[0]; @@ -977,7 +976,6 @@ static void get_options(int argc, char **argv) progname); exit(0); case '#': - DEBUGGER_ON; DBUG_PUSH (++pos); break; default: diff --git a/storage/myisam/mi_test3.c b/storage/myisam/mi_test3.c index be4277cc65c..4e764c6f971 100644 --- a/storage/myisam/mi_test3.c +++ b/storage/myisam/mi_test3.c @@ -120,7 +120,6 @@ int main(int argc,char **argv) static void get_options(int argc, char **argv) { char *pos,*progname; - DEBUGGER_OFF; progname= argv[0]; @@ -150,7 +149,6 @@ static void get_options(int argc, char **argv) printf("Usage: %s [-?lKA] [-f#] [-t#]\n",progname); exit(0); case '#': - DEBUGGER_ON; DBUG_PUSH (++pos); break; default: diff --git a/storage/ndb/src/ndbapi/DictCache.cpp b/storage/ndb/src/ndbapi/DictCache.cpp index d7a6e4c8586..5ea407ad48f 100644 --- a/storage/ndb/src/ndbapi/DictCache.cpp +++ b/storage/ndb/src/ndbapi/DictCache.cpp @@ -281,7 +281,7 @@ GlobalDictCache::drop(NdbTableImpl * tab) ver.m_refCount--; ver.m_status = DROPPED; if(ver.m_refCount == 0){ - DBUG_PRINT("info", ("refCount is zero, deleting m_impl")) + DBUG_PRINT("info", ("refCount is zero, deleting m_impl")); delete ver.m_impl; vers->erase(i); } diff --git a/storage/ndb/src/ndbapi/NdbTransaction.cpp b/storage/ndb/src/ndbapi/NdbTransaction.cpp index 294012d780c..fd0dc0eb124 100644 --- a/storage/ndb/src/ndbapi/NdbTransaction.cpp +++ b/storage/ndb/src/ndbapi/NdbTransaction.cpp @@ -978,7 +978,7 @@ void NdbTransaction::releaseExecutedScanOperation(NdbIndexScanOperation* cursorOp) { DBUG_ENTER("NdbTransaction::releaseExecutedScanOperation"); - DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp)) + DBUG_PRINT("enter", ("this=0x%x op=0x%x", (UintPtr)this, (UintPtr)cursorOp)); // here is one reason to make op lists doubly linked if (m_firstExecutedScanOp == cursorOp) { diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index e118289101e..745554406d5 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -15153,7 +15153,6 @@ int main(int argc, char **argv) { struct my_tests_st *fptr; - DEBUGGER_OFF; MY_INIT(argv[0]); load_defaults("my", client_test_load_default_groups, &argc, &argv); From 53031dae8515e735093fd602ed10615bff1c03e7 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 14 Feb 2006 22:51:16 +0100 Subject: [PATCH 2/4] my_bool is internal type, so should be SHOW_MY_BOOL --- include/plugin.h | 2 +- sql/sql_plugin.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/plugin.h b/include/plugin.h index 06eb0e91366..a7b3606061f 100644 --- a/include/plugin.h +++ b/include/plugin.h @@ -48,7 +48,7 @@ struct st_mysql_plugin _mysql_plugin_declarations_[]= { */ enum enum_mysql_show_type { - SHOW_UNDEF, SHOW_BOOL, SHOW_MY_BOOL, SHOW_INT, SHOW_LONG, + SHOW_UNDEF, SHOW_BOOL, SHOW_INT, SHOW_LONG, SHOW_LONGLONG, SHOW_CHAR, SHOW_CHAR_PTR, SHOW_ARRAY, SHOW_FUNC }; diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index ce06334ffd7..57808ff66d6 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -23,7 +23,7 @@ */ #define SHOW_FUNC SHOW_FUNC, SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_LONGLONG, \ SHOW_LONG_STATUS, SHOW_DOUBLE_STATUS, SHOW_HAVE, \ - SHOW_HA_ROWS, SHOW_SYS, SHOW_LONG_NOFLUSH + SHOW_MY_BOOL, SHOW_HA_ROWS, SHOW_SYS, SHOW_LONG_NOFLUSH #include #undef SHOW_FUNC typedef enum enum_mysql_show_type SHOW_TYPE; From bf3b67f3473f233cfead71a121040cee8bbd3198 Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Feb 2006 00:14:37 +0100 Subject: [PATCH 3/4] post-merge fixes for dbug dbug/dbug.c: post-merge fixes (-#T in explain was forgotten) sql/set_var.h: post-merge fixes (DBUG_POP() is the correct way to restore default settings now) --- dbug/dbug.c | 3 +++ sql/set_var.h | 7 +------ 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dbug/dbug.c b/dbug/dbug.c index e6323de1051..c212d55d815 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -67,6 +67,7 @@ * DBUG_EXECUTE_IF * incremental mode (-#+t:-d,info ...) * DBUG_SET, _db_explain_ + * thread-local settings * */ @@ -547,6 +548,7 @@ void _db_set_(CODE_STATE *cs, const char *control) if (!rel) sign=0; c= *control++; if (*control == ',') control++; + /* XXX when adding new cases here, don't forget _db_explain_ ! */ switch (c) { case 'd': if (sign < 0 && control == end) @@ -857,6 +859,7 @@ int _db_explain_ (CODE_STATE *cs, char *buf, int len) op_bool_to_buf('P', cs->stack->flags & PROCESS_ON); op_bool_to_buf('r', cs->stack->sub_level != 0); op_intf_to_buf('t', cs->stack->maxdepth, MAXDEPTH, TRACING); + op_bool_to_buf('T', cs->stack->flags & TIMESTAMP_ON); op_bool_to_buf('S', cs->stack->flags & SANITY_CHECK_ON); *buf= '\0'; diff --git a/sql/set_var.h b/sql/set_var.h index 9b640517e64..75c36176f91 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -435,12 +435,7 @@ public: bool check(THD *thd, set_var *var); SHOW_TYPE type() { return SHOW_CHAR; } bool update(THD *thd, set_var *var); - void set_default(THD *thd, enum_var_type type) - { - char buf[256]; - DBUG_EXPLAIN_INITIAL(buf, sizeof(buf)); - DBUG_SET(buf); - } + void set_default(THD *thd, enum_var_type type) { DBUG_POP(); } byte *value_ptr(THD *thd, enum_var_type type, LEX_STRING *b); }; From dac63fb8d23d465398c1e0aa68fa2a824275901a Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 15 Feb 2006 00:59:24 -0800 Subject: [PATCH 4/4] This patch adds a new field to the meta file for tracking flushes (this is being kept to later do stats and determine how often the compression buffer is being foiled). This should keep things all nice an compatible between versions. Also added a flush table test as well. Found one possible bug in OPTIMIZE TABLE which has never been reported, but I think it would be possible on a file system that ran out of disk. mysql-test/r/archive.result: New results mysql-test/t/archive.test: Added test for flush tables, which will also let me confirm DELAYED INSERT. sql/ha_archive.cc: Adding new stat sql/ha_archive.h: Just extending SHARE --- mysql-test/r/archive.result | 1217 +++++++++++++++++++++++++++++++++++ mysql-test/t/archive.test | 6 +- sql/ha_archive.cc | 54 +- sql/ha_archive.h | 10 +- 4 files changed, 1269 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index 26d95a4dc8d..fd4da80566b 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -11119,6 +11119,1223 @@ auto fld1 companynr fld3 fld4 fld5 fld6 3 011402 37 Romans scholastics jarring 4 011403 37 intercepted audiology tinily INSERT DELAYED INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily',''); +FLUSH TABLE t2; +SELECT * FROM t2; +auto fld1 companynr fld3 fld4 fld5 fld6 +1 000001 00 Omaha teethe neat +2 011401 37 breaking dreaded Steinberg W +3 011402 37 Romans scholastics jarring +4 011403 37 intercepted audiology tinily +5 011501 37 bewilderingly wallet balled +6 011701 37 astound parters persist W +7 011702 37 admonishing eschew attainments +8 011703 37 sumac quitter fanatic +9 012001 37 flanking neat measures FAS +10 012003 37 combed Steinberg rightfulness +11 012004 37 subjective jarring capably +12 012005 37 scatterbrain tinily impulsive +13 012301 37 Eulerian balled starlet +14 012302 36 dubbed persist terminators +15 012303 37 Kane attainments untying +16 012304 37 overlay fanatic announces FAS +17 012305 37 perturb measures featherweight FAS +18 012306 37 goblins rightfulness pessimist FAS +19 012501 37 annihilates capably daughter +20 012602 37 Wotan impulsive decliner FAS +21 012603 37 snatching starlet lawgiver +22 012604 37 concludes terminators stated +23 012605 37 laterally untying readable +24 012606 37 yelped announces attrition +25 012701 37 grazing featherweight cascade FAS +26 012702 37 Baird pessimist motors FAS +27 012703 37 celery daughter interrogate +28 012704 37 misunderstander decliner pests W +29 013601 37 handgun lawgiver stairway +30 013602 37 foldout stated dopers FAS +31 013603 37 mystic readable testicle W +32 013604 37 succumbed attrition Parsifal W +33 013605 37 Nabisco cascade leavings +34 013606 37 fingerings motors postulation W +35 013607 37 aging interrogate squeaking +36 013608 37 afield pests contrasted +37 013609 37 ammonium stairway leftover +38 013610 37 boat dopers whiteners +39 013801 37 intelligibility testicle erases W +40 013802 37 Augustine Parsifal Punjab W +41 013803 37 teethe leavings Merritt +42 013804 37 dreaded postulation Quixotism +43 013901 37 scholastics squeaking sweetish FAS +44 016001 37 audiology contrasted dogging FAS +45 016201 37 wallet leftover scornfully FAS +46 016202 37 parters whiteners bellow +47 016301 37 eschew erases bills +48 016302 37 quitter Punjab cupboard FAS +49 016303 37 neat Merritt sureties FAS +50 016304 37 Steinberg Quixotism puddings +51 018001 37 jarring sweetish tapestry +52 018002 37 tinily dogging fetters +53 018003 37 balled scornfully bivalves +54 018004 37 persist bellow incurring +55 018005 37 attainments bills Adolph +56 018007 37 fanatic cupboard pithed +57 018008 37 measures sureties emergency +58 018009 37 rightfulness puddings Miles +59 018010 37 capably tapestry trimmings +60 018012 37 impulsive fetters tragedies W +61 018013 37 starlet bivalves skulking W +62 018014 37 terminators incurring flint +63 018015 37 untying Adolph flopping W +64 018016 37 announces pithed relaxing FAS +65 018017 37 featherweight emergency offload FAS +66 018018 37 pessimist Miles suites W +67 018019 37 daughter trimmings lists FAS +68 018020 37 decliner tragedies animized FAS +69 018021 37 lawgiver skulking multilayer W +70 018022 37 stated flint standardizes FAS +71 018023 37 readable flopping Judas +72 018024 37 attrition relaxing vacuuming W +73 018025 37 cascade offload dentally W +74 018026 37 motors suites humanness W +75 018027 37 interrogate lists inch W +76 018028 37 pests animized Weissmuller W +77 018029 37 stairway multilayer irresponsibly W +78 018030 37 dopers standardizes luckily FAS +79 018032 37 testicle Judas culled W +80 018033 37 Parsifal vacuuming medical FAS +81 018034 37 leavings dentally bloodbath FAS +82 018035 37 postulation humanness subschema W +83 018036 37 squeaking inch animals W +84 018037 37 contrasted Weissmuller Micronesia +85 018038 37 leftover irresponsibly repetitions +86 018039 37 whiteners luckily Antares +87 018040 37 erases culled ventilate W +88 018041 37 Punjab medical pityingly +89 018042 37 Merritt bloodbath interdependent +90 018043 37 Quixotism subschema Graves FAS +91 018044 37 sweetish animals neonatal +92 018045 37 dogging Micronesia scribbled FAS +93 018046 37 scornfully repetitions chafe W +94 018048 37 bellow Antares honoring +95 018049 37 bills ventilate realtor +96 018050 37 cupboard pityingly elite +97 018051 37 sureties interdependent funereal +98 018052 37 puddings Graves abrogating +99 018053 50 tapestry neonatal sorters +100 018054 37 fetters scribbled Conley +101 018055 37 bivalves chafe lectured +102 018056 37 incurring honoring Abraham +103 018057 37 Adolph realtor Hawaii W +104 018058 37 pithed elite cage +105 018059 36 emergency funereal hushes +106 018060 37 Miles abrogating Simla +107 018061 37 trimmings sorters reporters +108 018101 37 tragedies Conley Dutchman FAS +109 018102 37 skulking lectured descendants FAS +110 018103 37 flint Abraham groupings FAS +111 018104 37 flopping Hawaii dissociate +112 018201 37 relaxing cage coexist W +113 018202 37 offload hushes Beebe +114 018402 37 suites Simla Taoism +115 018403 37 lists reporters Connally +116 018404 37 animized Dutchman fetched FAS +117 018405 37 multilayer descendants checkpoints FAS +118 018406 37 standardizes groupings rusting +119 018409 37 Judas dissociate galling +120 018601 37 vacuuming coexist obliterates +121 018602 37 dentally Beebe traitor +122 018603 37 humanness Taoism resumes FAS +123 018801 37 inch Connally analyzable FAS +124 018802 37 Weissmuller fetched terminator FAS +125 018803 37 irresponsibly checkpoints gritty FAS +126 018804 37 luckily rusting firearm W +127 018805 37 culled galling minima +128 018806 37 medical obliterates Selfridge +129 018807 37 bloodbath traitor disable +130 018808 37 subschema resumes witchcraft W +131 018809 37 animals analyzable betroth W +132 018810 37 Micronesia terminator Manhattanize +133 018811 37 repetitions gritty imprint +134 018812 37 Antares firearm peeked +135 019101 37 ventilate minima swelling +136 019102 37 pityingly Selfridge interrelationships W +137 019103 37 interdependent disable riser +138 019201 37 Graves witchcraft Gandhian W +139 030501 37 neonatal betroth peacock A +140 030502 50 scribbled Manhattanize bee A +141 030503 37 chafe imprint kanji +142 030504 37 honoring peeked dental +143 031901 37 realtor swelling scarf FAS +144 036001 37 elite interrelationships chasm A +145 036002 37 funereal riser insolence A +146 036004 37 abrogating Gandhian syndicate +147 036005 37 sorters peacock alike +148 038001 37 Conley bee imperial A +149 038002 37 lectured kanji convulsion A +150 038003 37 Abraham dental railway A +151 038004 37 Hawaii scarf validate A +152 038005 37 cage chasm normalizes A +153 038006 37 hushes insolence comprehensive +154 038007 37 Simla syndicate chewing +155 038008 37 reporters alike denizen +156 038009 37 Dutchman imperial schemer +157 038010 37 descendants convulsion chronicle +158 038011 37 groupings railway Kline +159 038012 37 dissociate validate Anatole +160 038013 37 coexist normalizes partridges +161 038014 37 Beebe comprehensive brunch +162 038015 37 Taoism chewing recruited +163 038016 37 Connally denizen dimensions W +164 038017 37 fetched schemer Chicana W +165 038018 37 checkpoints chronicle announced +166 038101 37 rusting Kline praised FAS +167 038102 37 galling Anatole employing +168 038103 37 obliterates partridges linear +169 038104 37 traitor brunch quagmire +170 038201 37 resumes recruited western A +171 038202 37 analyzable dimensions relishing +172 038203 37 terminator Chicana serving A +173 038204 37 gritty announced scheduling +174 038205 37 firearm praised lore +175 038206 37 minima employing eventful +176 038208 37 Selfridge linear arteriole A +177 042801 37 disable quagmire disentangle +178 042802 37 witchcraft western cured A +179 046101 37 betroth relishing Fenton W +180 048001 37 Manhattanize serving avoidable A +181 048002 37 imprint scheduling drains A +182 048003 37 peeked lore detectably FAS +183 048004 37 swelling eventful husky +184 048005 37 interrelationships arteriole impelling +185 048006 37 riser disentangle undoes +186 048007 37 Gandhian cured evened +187 048008 37 peacock Fenton squeezes +188 048101 37 bee avoidable destroyer FAS +189 048102 37 kanji drains rudeness +190 048201 37 dental detectably beaner FAS +191 048202 37 scarf husky boorish +192 048203 37 chasm impelling Everhart +193 048204 37 insolence undoes encompass A +194 048205 37 syndicate evened mushrooms +195 048301 37 alike squeezes Alison A +196 048302 37 imperial destroyer externally FAS +197 048303 37 convulsion rudeness pellagra +198 048304 37 railway beaner cult +199 048305 37 validate boorish creek A +200 048401 37 normalizes Everhart Huffman +201 048402 37 comprehensive encompass Majorca FAS +202 048403 37 chewing mushrooms governing A +203 048404 37 denizen Alison gadfly FAS +204 048405 37 schemer externally reassigned FAS +205 048406 37 chronicle pellagra intentness W +206 048407 37 Kline cult craziness +207 048408 37 Anatole creek psychic +208 048409 37 partridges Huffman squabbled +209 048410 37 brunch Majorca burlesque +210 048411 37 recruited governing capped +211 048412 37 dimensions gadfly extracted A +212 048413 37 Chicana reassigned DiMaggio +213 048601 37 announced intentness exclamation FAS +214 048602 37 praised craziness subdirectory +215 048603 37 employing psychic fangs +216 048604 37 linear squabbled buyer A +217 048801 37 quagmire burlesque pithing A +218 050901 37 western capped transistorizing A +219 051201 37 relishing extracted nonbiodegradable +220 056002 37 serving DiMaggio dislocate +221 056003 37 scheduling exclamation monochromatic FAS +222 056004 37 lore subdirectory batting +223 056102 37 eventful fangs postcondition A +224 056203 37 arteriole buyer catalog FAS +225 056204 37 disentangle pithing Remus +226 058003 37 cured transistorizing devices A +227 058004 37 Fenton nonbiodegradable bike A +228 058005 37 avoidable dislocate qualify +229 058006 37 drains monochromatic detained +230 058007 37 detectably batting commended +231 058101 37 husky postcondition civilize +232 058102 37 impelling catalog Elmhurst +233 058103 37 undoes Remus anesthetizing +234 058105 37 evened devices deaf +235 058111 37 squeezes bike Brigham +236 058112 37 destroyer qualify title +237 058113 37 rudeness detained coarse +238 058114 37 beaner commended combinations +239 058115 37 boorish civilize grayness +240 058116 37 Everhart Elmhurst innumerable FAS +241 058117 37 encompass anesthetizing Caroline A +242 058118 37 mushrooms deaf fatty FAS +243 058119 37 Alison Brigham eastbound +244 058120 37 externally title inexperienced +245 058121 37 pellagra coarse hoarder A +246 058122 37 cult combinations scotch W +247 058123 37 creek grayness passport A +248 058124 37 Huffman innumerable strategic FAS +249 058125 37 Majorca Caroline gated +250 058126 37 governing fatty flog +251 058127 37 gadfly eastbound Pipestone +252 058128 37 reassigned inexperienced Dar +253 058201 37 intentness hoarder Corcoran +254 058202 37 craziness scotch flyers A +255 058303 37 psychic passport competitions W +256 058304 37 squabbled strategic suppliers FAS +257 058602 37 burlesque gated skips +258 058603 37 capped flog institutes +259 058604 37 extracted Pipestone troop A +260 058605 37 DiMaggio Dar connective W +261 058606 37 exclamation Corcoran denies +262 058607 37 subdirectory flyers polka +263 060401 36 fangs competitions observations FAS +264 061701 36 buyer suppliers askers +265 066201 36 pithing skips homeless FAS +266 066501 36 transistorizing institutes Anna +267 068001 36 nonbiodegradable troop subdirectories W +268 068002 36 dislocate connective decaying FAS +269 068005 36 monochromatic denies outwitting W +270 068006 36 batting polka Harpy W +271 068007 36 postcondition observations crazed +272 068008 36 catalog askers suffocate +273 068009 36 Remus homeless provers FAS +274 068010 36 devices Anna technically +275 068011 36 bike subdirectories Franklinizations +276 068202 36 qualify decaying considered +277 068302 36 detained outwitting tinnily +278 068303 36 commended Harpy uninterruptedly +279 068401 36 civilize crazed whistled A +280 068501 36 Elmhurst suffocate automate +281 068502 36 anesthetizing provers gutting W +282 068503 36 deaf technically surreptitious +283 068602 36 Brigham Franklinizations Choctaw +284 068603 36 title considered cooks +285 068701 36 coarse tinnily millivolt FAS +286 068702 36 combinations uninterruptedly counterpoise +287 068703 36 grayness whistled Gothicism +288 076001 36 innumerable automate feminine +289 076002 36 Caroline gutting metaphysically W +290 076101 36 fatty surreptitious sanding A +291 076102 36 eastbound Choctaw contributorily +292 076103 36 inexperienced cooks receivers FAS +293 076302 36 hoarder millivolt adjourn +294 076303 36 scotch counterpoise straggled A +295 076304 36 passport Gothicism druggists +296 076305 36 strategic feminine thanking FAS +297 076306 36 gated metaphysically ostrich +298 076307 36 flog sanding hopelessness FAS +299 076402 36 Pipestone contributorily Eurydice +300 076501 36 Dar receivers excitation W +301 076502 36 Corcoran adjourn presumes FAS +302 076701 36 flyers straggled imaginable FAS +303 078001 36 competitions druggists concoct W +304 078002 36 suppliers thanking peering W +305 078003 36 skips ostrich Phelps FAS +306 078004 36 institutes hopelessness ferociousness FAS +307 078005 36 troop Eurydice sentences +308 078006 36 connective excitation unlocks +309 078007 36 denies presumes engrossing W +310 078008 36 polka imaginable Ruth +311 078101 36 observations concoct tying +312 078103 36 askers peering exclaimers +313 078104 36 homeless Phelps synergy +314 078105 36 Anna ferociousness Huey W +315 082101 36 subdirectories sentences merging +316 083401 36 decaying unlocks judges A +317 084001 36 outwitting engrossing Shylock W +318 084002 36 Harpy Ruth Miltonism +319 086001 36 crazed tying hen W +320 086102 36 suffocate exclaimers honeybee FAS +321 086201 36 provers synergy towers +322 088001 36 technically Huey dilutes W +323 088002 36 Franklinizations merging numerals FAS +324 088003 36 considered judges democracy FAS +325 088004 36 tinnily Shylock Ibero- +326 088101 36 uninterruptedly Miltonism invalids +327 088102 36 whistled hen behavior +328 088103 36 automate honeybee accruing +329 088104 36 gutting towers relics A +330 088105 36 surreptitious dilutes rackets +331 088106 36 Choctaw numerals Fischbein W +332 088201 36 cooks democracy phony W +333 088203 36 millivolt Ibero- cross FAS +334 088204 36 counterpoise invalids cleanup +335 088302 37 Gothicism behavior conspirator +336 088303 37 feminine accruing label FAS +337 088305 37 metaphysically relics university +338 088402 37 sanding rackets cleansed FAS +339 088501 36 contributorily Fischbein ballgown +340 088502 36 receivers phony starlet +341 088503 36 adjourn cross aqueous +342 098001 58 straggled cleanup portrayal A +343 098002 58 druggists conspirator despising W +344 098003 58 thanking label distort W +345 098004 58 ostrich university palmed +346 098005 58 hopelessness cleansed faced +347 098006 58 Eurydice ballgown silverware +348 141903 29 excitation starlet assessor +349 098008 58 presumes aqueous spiders +350 098009 58 imaginable portrayal artificially +351 098010 58 concoct despising reminiscence +352 098011 58 peering distort Mexican +353 098012 58 Phelps palmed obnoxious +354 098013 58 ferociousness faced fragile +355 098014 58 sentences silverware apprehensible +356 098015 58 unlocks assessor births +357 098016 58 engrossing spiders garages +358 098017 58 Ruth artificially panty +359 098018 58 tying reminiscence anteater +360 098019 58 exclaimers Mexican displacement A +361 098020 58 synergy obnoxious drovers A +362 098021 58 Huey fragile patenting A +363 098022 58 merging apprehensible far A +364 098023 58 judges births shrieks +365 098024 58 Shylock garages aligning W +366 098025 37 Miltonism panty pragmatism +367 106001 36 hen anteater fevers W +368 108001 36 honeybee displacement reexamines A +369 108002 36 towers drovers occupancies +370 108003 36 dilutes patenting sweats FAS +371 108004 36 numerals far modulators +372 108005 36 democracy shrieks demand W +373 108007 36 Ibero- aligning Madeira +374 108008 36 invalids pragmatism Viennese W +375 108009 36 behavior fevers chillier W +376 108010 36 accruing reexamines wildcats FAS +377 108011 36 relics occupancies gentle +378 108012 36 rackets sweats Angles W +379 108101 36 Fischbein modulators accuracies +380 108102 36 phony demand toggle +381 108103 36 cross Madeira Mendelssohn W +382 108111 50 cleanup Viennese behaviorally +383 108105 36 conspirator chillier Rochford +384 108106 36 label wildcats mirror W +385 108107 36 university gentle Modula +386 108108 50 cleansed Angles clobbering +387 108109 36 ballgown accuracies chronography +388 108110 36 starlet toggle Eskimoizeds +389 108201 36 aqueous Mendelssohn British W +390 108202 36 portrayal behaviorally pitfalls +391 108203 36 despising Rochford verify W +392 108204 36 distort mirror scatter FAS +393 108205 36 palmed Modula Aztecan +394 108301 36 faced clobbering acuity W +395 108302 36 silverware chronography sinking W +396 112101 36 assessor Eskimoizeds beasts FAS +397 112102 36 spiders British Witt W +398 113701 36 artificially pitfalls physicists FAS +399 116001 36 reminiscence verify folksong A +400 116201 36 Mexican scatter strokes FAS +401 116301 36 obnoxious Aztecan crowder +402 116302 36 fragile acuity merry +403 116601 36 apprehensible sinking cadenced +404 116602 36 births beasts alimony A +405 116603 36 garages Witt principled A +406 116701 36 panty physicists golfing +407 116702 36 anteater folksong undiscovered +408 118001 36 displacement strokes irritates +409 118002 36 drovers crowder patriots A +410 118003 36 patenting merry rooms FAS +411 118004 36 far cadenced towering W +412 118005 36 shrieks alimony displease +413 118006 36 aligning principled photosensitive +414 118007 36 pragmatism golfing inking +415 118008 36 fevers undiscovered gainers +416 118101 36 reexamines irritates leaning A +417 118102 36 occupancies patriots hydrant A +418 118103 36 sweats rooms preserve +419 118202 36 modulators towering blinded A +420 118203 36 demand displease interactions A +421 118204 36 Madeira photosensitive Barry +422 118302 36 Viennese inking whiteness A +423 118304 36 chillier gainers pastimes W +424 118305 36 wildcats leaning Edenization +425 118306 36 gentle hydrant Muscat +426 118307 36 Angles preserve assassinated +427 123101 36 accuracies blinded labeled +428 123102 36 toggle interactions glacial A +429 123301 36 Mendelssohn Barry implied W +430 126001 36 behaviorally whiteness bibliographies W +431 126002 36 Rochford pastimes Buchanan +432 126003 36 mirror Edenization forgivably FAS +433 126101 36 Modula Muscat innuendo A +434 126301 36 clobbering assassinated den FAS +435 126302 36 chronography labeled submarines W +436 126402 36 Eskimoizeds glacial mouthful A +437 126601 36 British implied expiring +438 126602 36 pitfalls bibliographies unfulfilled FAS +439 126702 36 verify Buchanan precession +440 128001 36 scatter forgivably nullified +441 128002 36 Aztecan innuendo affects +442 128003 36 acuity den Cynthia +443 128004 36 sinking submarines Chablis A +444 128005 36 beasts mouthful betterments FAS +445 128007 36 Witt expiring advertising +446 128008 36 physicists unfulfilled rubies A +447 128009 36 folksong precession southwest FAS +448 128010 36 strokes nullified superstitious A +449 128011 36 crowder affects tabernacle W +450 128012 36 merry Cynthia silk A +451 128013 36 cadenced Chablis handsomest A +452 128014 36 alimony betterments Persian A +453 128015 36 principled advertising analog W +454 128016 36 golfing rubies complex W +455 128017 36 undiscovered southwest Taoist +456 128018 36 irritates superstitious suspend +457 128019 36 patriots tabernacle relegated +458 128020 36 rooms silk awesome W +459 128021 36 towering handsomest Bruxelles +460 128022 36 displease Persian imprecisely A +461 128023 36 photosensitive analog televise +462 128101 36 inking complex braking +463 128102 36 gainers Taoist true FAS +464 128103 36 leaning suspend disappointing FAS +465 128104 36 hydrant relegated navally W +466 128106 36 preserve awesome circus +467 128107 36 blinded Bruxelles beetles +468 128108 36 interactions imprecisely trumps +469 128202 36 Barry televise fourscore W +470 128203 36 whiteness braking Blackfoots +471 128301 36 pastimes true Grady +472 128302 36 Edenization disappointing quiets FAS +473 128303 36 Muscat navally floundered FAS +474 128304 36 assassinated circus profundity W +475 128305 36 labeled beetles Garrisonian W +476 128307 36 glacial trumps Strauss +477 128401 36 implied fourscore cemented FAS +478 128502 36 bibliographies Blackfoots contrition A +479 128503 36 Buchanan Grady mutations +480 128504 36 forgivably quiets exhibits W +481 128505 36 innuendo floundered tits +482 128601 36 den profundity mate A +483 128603 36 submarines Garrisonian arches +484 128604 36 mouthful Strauss Moll +485 128702 36 expiring cemented ropers +486 128703 36 unfulfilled contrition bombast +487 128704 36 precession mutations difficultly A +488 138001 36 nullified exhibits adsorption +489 138002 36 affects tits definiteness FAS +490 138003 36 Cynthia mate cultivation A +491 138004 36 Chablis arches heals A +492 138005 36 betterments Moll Heusen W +493 138006 36 advertising ropers target FAS +494 138007 36 rubies bombast cited A +495 138008 36 southwest difficultly congresswoman W +496 138009 36 superstitious adsorption Katherine +497 138102 36 tabernacle definiteness titter A +498 138103 36 silk cultivation aspire A +499 138104 36 handsomest heals Mardis +500 138105 36 Persian Heusen Nadia W +501 138201 36 analog target estimating FAS +502 138302 36 complex cited stuck A +503 138303 36 Taoist congresswoman fifteenth A +504 138304 36 suspend Katherine Colombo +505 138401 29 relegated titter survey A +506 140102 29 awesome aspire staffing +507 140103 29 Bruxelles Mardis obtain +508 140104 29 imprecisely Nadia loaded +509 140105 29 televise estimating slaughtered +510 140201 29 braking stuck lights A +511 140701 29 true fifteenth circumference +512 141501 29 disappointing Colombo dull A +513 141502 29 navally survey weekly A +514 141901 29 circus staffing wetness +515 141902 29 beetles obtain visualized +516 142101 29 trumps loaded Tannenbaum +517 142102 29 fourscore slaughtered moribund +518 142103 29 Blackfoots lights demultiplex +519 142701 29 Grady circumference lockings +520 143001 29 quiets dull thugs FAS +521 143501 29 floundered weekly unnerves +522 143502 29 profundity wetness abut +523 148001 29 Garrisonian visualized Chippewa A +524 148002 29 Strauss Tannenbaum stratifications A +525 148003 29 cemented moribund signaled +526 148004 29 contrition demultiplex Italianizes A +527 148005 29 mutations lockings algorithmic A +528 148006 29 exhibits thugs paranoid FAS +529 148007 29 tits unnerves camping A +530 148009 29 mate abut signifying A +531 148010 29 arches Chippewa Patrice W +532 148011 29 Moll stratifications search A +533 148012 29 ropers signaled Angeles A +534 148013 29 bombast Italianizes semblance +535 148023 36 difficultly algorithmic taxed +536 148015 29 adsorption paranoid Beatrice +537 148016 29 definiteness camping retrace +538 148017 29 cultivation signifying lockout +539 148018 29 heals Patrice grammatic +540 148019 29 Heusen search helmsman +541 148020 29 target Angeles uniform W +542 148021 29 cited semblance hamming +543 148022 29 congresswoman taxed disobedience +544 148101 29 Katherine Beatrice captivated A +545 148102 29 titter retrace transferals A +546 148201 29 aspire lockout cartographer A +547 148401 29 Mardis grammatic aims FAS +548 148402 29 Nadia helmsman Pakistani +549 148501 29 estimating uniform burglarized FAS +550 148502 29 stuck hamming saucepans A +551 148503 29 fifteenth disobedience lacerating A +552 148504 29 Colombo captivated corny +553 148601 29 survey transferals megabytes FAS +554 148602 29 staffing cartographer chancellor +555 150701 29 obtain aims bulk A +556 152101 29 loaded Pakistani commits A +557 152102 29 slaughtered burglarized meson W +558 155202 36 lights saucepans deputies +559 155203 29 circumference lacerating northeaster A +560 155204 29 dull corny dipole +561 155205 29 weekly megabytes machining 0 +562 156001 29 wetness chancellor therefore +563 156002 29 visualized bulk Telefunken +564 156102 29 Tannenbaum commits salvaging +565 156301 29 moribund meson Corinthianizes A +566 156302 29 demultiplex deputies restlessly A +567 156303 29 lockings northeaster bromides +568 156304 29 thugs dipole generalized A +569 156305 29 unnerves machining mishaps +570 156306 29 abut therefore quelling +571 156501 29 Chippewa Telefunken spiritual A +572 158001 29 stratifications salvaging beguiles FAS +573 158002 29 signaled Corinthianizes Trobriand FAS +574 158101 29 Italianizes restlessly fleeing A +575 158102 29 algorithmic bromides Armour A +576 158103 29 paranoid generalized chin A +577 158201 29 camping mishaps provers A +578 158202 29 signifying quelling aeronautic A +579 158203 29 Patrice spiritual voltage W +580 158204 29 search beguiles sash +581 158301 29 Angeles Trobriand anaerobic A +582 158302 29 semblance fleeing simultaneous A +583 158303 29 taxed Armour accumulating A +584 158304 29 Beatrice chin Medusan A +585 158305 29 retrace provers shouted A +586 158306 29 lockout aeronautic freakish +587 158501 29 grammatic voltage index FAS +588 160301 29 helmsman sash commercially +589 166101 50 uniform anaerobic mistiness A +590 166102 50 hamming simultaneous endpoint +591 168001 29 disobedience accumulating straight A +592 168002 29 captivated Medusan flurried +593 168003 29 transferals shouted denotative A +594 168101 29 cartographer freakish coming FAS +595 168102 29 aims index commencements FAS +596 168103 29 Pakistani commercially gentleman +597 168104 29 burglarized mistiness gifted +598 168202 29 saucepans endpoint Shanghais +599 168301 29 lacerating straight sportswriting A +600 168502 29 corny flurried sloping A +601 168503 29 megabytes denotative navies +602 168601 29 chancellor coming leaflet A +603 173001 40 bulk commencements shooter +604 173701 40 commits gentleman Joplin FAS +605 173702 40 meson gifted babies +606 176001 40 deputies Shanghais subdivision FAS +607 176101 40 northeaster sportswriting burstiness W +608 176201 40 dipole sloping belted FAS +609 176401 40 machining navies assails FAS +610 176501 40 therefore leaflet admiring W +611 176601 40 Telefunken shooter swaying 0 +612 176602 40 salvaging Joplin Goldstine FAS +613 176603 40 Corinthianizes babies fitting +614 178001 40 restlessly subdivision Norwalk W +615 178002 40 bromides burstiness weakening W +616 178003 40 generalized belted analogy FAS +617 178004 40 mishaps assails deludes +618 178005 40 quelling admiring cokes +619 178006 40 spiritual swaying Clayton +620 178007 40 beguiles Goldstine exhausts +621 178008 40 Trobriand fitting causality +622 178101 40 fleeing Norwalk sating FAS +623 178102 40 Armour weakening icon +624 178103 40 chin analogy throttles +625 178201 40 provers deludes communicants FAS +626 178202 40 aeronautic cokes dehydrate FAS +627 178301 40 voltage Clayton priceless FAS +628 178302 40 sash exhausts publicly +629 178401 40 anaerobic causality incidentals FAS +630 178402 40 simultaneous sating commonplace +631 178403 40 accumulating icon mumbles +632 178404 40 Medusan throttles furthermore W +633 178501 40 shouted communicants cautioned W +634 186002 37 freakish dehydrate parametrized A +635 186102 37 index priceless registration A +636 186201 40 commercially publicly sadly FAS +637 186202 40 mistiness incidentals positioning +638 186203 40 endpoint commonplace babysitting +639 186302 37 straight mumbles eternal A +640 188007 37 flurried furthermore hoarder +641 188008 37 denotative cautioned congregates +642 188009 37 coming parametrized rains +643 188010 37 commencements registration workers W +644 188011 37 gentleman sadly sags A +645 188012 37 gifted positioning unplug W +646 188013 37 Shanghais babysitting garage A +647 188014 37 sportswriting eternal boulder A +648 188015 37 sloping hoarder hollowly A +649 188016 37 navies congregates specifics +650 188017 37 leaflet rains Teresa +651 188102 37 shooter workers Winsett +652 188103 37 Joplin sags convenient A +653 188202 37 babies unplug buckboards FAS +654 188301 40 subdivision garage amenities +655 188302 40 burstiness boulder resplendent FAS +656 188303 40 belted hollowly priding FAS +657 188401 37 assails specifics configurations +658 188402 37 admiring Teresa untidiness A +659 188503 37 swaying Winsett Brice W +660 188504 37 Goldstine convenient sews FAS +661 188505 37 fitting buckboards participated +662 190701 37 Norwalk amenities Simon FAS +663 190703 50 weakening resplendent certificates +664 191701 37 analogy priding Fitzpatrick +665 191702 37 deludes configurations Evanston A +666 191703 37 cokes untidiness misted +667 196001 37 Clayton Brice textures A +668 196002 37 exhausts sews save +669 196003 37 causality participated count +670 196101 37 sating Simon rightful A +671 196103 37 icon certificates chaperone +672 196104 37 throttles Fitzpatrick Lizzy A +673 196201 37 communicants Evanston clenched A +674 196202 37 dehydrate misted effortlessly +675 196203 37 priceless textures accessed +676 198001 37 publicly save beaters A +677 198003 37 incidentals count Hornblower FAS +678 198004 37 commonplace rightful vests A +679 198005 37 mumbles chaperone indulgences FAS +680 198006 37 furthermore Lizzy infallibly A +681 198007 37 cautioned clenched unwilling FAS +682 198008 37 parametrized effortlessly excrete FAS +683 198009 37 registration accessed spools A +684 198010 37 sadly beaters crunches FAS +685 198011 37 positioning Hornblower overestimating FAS +686 198012 37 babysitting vests ineffective +687 198013 37 eternal indulgences humiliation A +688 198014 37 hoarder infallibly sophomore +689 198015 37 congregates unwilling star +690 198017 37 rains excrete rifles +691 198018 37 workers spools dialysis +692 198019 37 sags crunches arriving +693 198020 37 unplug overestimating indulge +694 198021 37 garage ineffective clockers +695 198022 37 boulder humiliation languages +696 198023 50 hollowly sophomore Antarctica A +697 198024 37 specifics star percentage +698 198101 37 Teresa rifles ceiling A +699 198103 37 Winsett dialysis specification +700 198105 37 convenient arriving regimented A +701 198106 37 buckboards indulge ciphers +702 198201 37 amenities clockers pictures A +703 198204 37 resplendent languages serpents A +704 198301 53 priding Antarctica allot A +705 198302 53 configurations percentage realized A +706 198303 53 untidiness ceiling mayoral A +707 198304 53 Brice specification opaquely A +708 198401 37 sews regimented hostess FAS +709 198402 37 participated ciphers fiftieth +710 198403 37 Simon pictures incorrectly +711 202101 37 certificates serpents decomposition FAS +712 202301 37 Fitzpatrick allot stranglings +713 202302 37 Evanston realized mixture FAS +714 202303 37 misted mayoral electroencephalography FAS +715 202304 37 textures opaquely similarities FAS +716 202305 37 save hostess charges W +717 202601 37 count fiftieth freest FAS +718 202602 37 rightful incorrectly Greenberg FAS +719 202605 37 chaperone decomposition tinting +720 202606 37 Lizzy stranglings expelled W +721 202607 37 clenched mixture warm +722 202901 37 effortlessly electroencephalography smoothed +723 202902 37 accessed similarities deductions FAS +724 202903 37 beaters charges Romano W +725 202904 37 Hornblower freest bitterroot +726 202907 37 vests Greenberg corset +727 202908 37 indulgences tinting securing +728 203101 37 infallibly expelled environing FAS +729 203103 37 unwilling warm cute +730 203104 37 excrete smoothed Crays +731 203105 37 spools deductions heiress FAS +732 203401 37 crunches Romano inform FAS +733 203402 37 overestimating bitterroot avenge +734 203404 37 ineffective corset universals +735 203901 37 humiliation securing Kinsey W +736 203902 37 sophomore environing ravines FAS +737 203903 37 star cute bestseller +738 203906 37 rifles Crays equilibrium +739 203907 37 dialysis heiress extents 0 +740 203908 37 arriving inform relatively +741 203909 37 indulge avenge pressure FAS +742 206101 37 clockers universals critiques FAS +743 206201 37 languages Kinsey befouled +744 206202 37 Antarctica ravines rightfully FAS +745 206203 37 percentage bestseller mechanizing FAS +746 206206 37 ceiling equilibrium Latinizes +747 206207 37 specification extents timesharing +748 206208 37 regimented relatively Aden +749 208001 37 ciphers pressure embassies +750 208002 37 pictures critiques males FAS +751 208003 37 serpents befouled shapelessly FAS +752 208004 37 allot rightfully genres FAS +753 208008 37 realized mechanizing mastering +754 208009 37 mayoral Latinizes Newtonian +755 208010 37 opaquely timesharing finishers FAS +756 208011 37 hostess Aden abates +757 208101 37 fiftieth embassies teem +758 208102 37 incorrectly males kiting FAS +759 208103 37 decomposition shapelessly stodgy FAS +760 208104 37 stranglings genres scalps FAS +761 208105 37 mixture mastering feed FAS +762 208110 37 electroencephalography Newtonian guitars +763 208111 37 similarities finishers airships +764 208112 37 charges abates store +765 208113 37 freest teem denounces +766 208201 37 Greenberg kiting Pyle FAS +767 208203 37 tinting stodgy Saxony +768 208301 37 expelled scalps serializations FAS +769 208302 37 warm feed Peruvian FAS +770 208305 37 smoothed guitars taxonomically FAS +771 208401 37 deductions airships kingdom A +772 208402 37 Romano store stint A +773 208403 37 bitterroot denounces Sault A +774 208404 37 corset Pyle faithful +775 208501 37 securing Saxony Ganymede FAS +776 208502 37 environing serializations tidiness FAS +777 208503 37 cute Peruvian gainful FAS +778 208504 37 Crays taxonomically contrary FAS +779 208505 37 heiress kingdom Tipperary FAS +780 210101 37 inform stint tropics W +781 210102 37 avenge Sault theorizers +782 210103 37 universals faithful renew 0 +783 210104 37 Kinsey Ganymede already +784 210105 37 ravines tidiness terminal +785 210106 37 bestseller gainful Hegelian +786 210107 37 equilibrium contrary hypothesizer +787 210401 37 extents Tipperary warningly FAS +788 213201 37 relatively tropics journalizing FAS +789 213203 37 pressure theorizers nested +790 213204 37 critiques renew Lars +791 213205 37 befouled already saplings +792 213206 37 rightfully terminal foothill +793 213207 37 mechanizing Hegelian labeled +794 216101 37 Latinizes hypothesizer imperiously FAS +795 216103 37 timesharing warningly reporters FAS +796 218001 37 Aden journalizing furnishings FAS +797 218002 37 embassies nested precipitable FAS +798 218003 37 males Lars discounts FAS +799 218004 37 shapelessly saplings excises FAS +800 143503 50 genres foothill Stalin +801 218006 37 mastering labeled despot FAS +802 218007 37 Newtonian imperiously ripeness FAS +803 218008 37 finishers reporters Arabia +804 218009 37 abates furnishings unruly +805 218010 37 teem precipitable mournfulness +806 218011 37 kiting discounts boom FAS +807 218020 37 stodgy excises slaughter A +808 218021 50 scalps Stalin Sabine +809 218022 37 feed despot handy FAS +810 218023 37 guitars ripeness rural +811 218024 37 airships Arabia organizer +812 218101 37 store unruly shipyard FAS +813 218102 37 denounces mournfulness civics FAS +814 218103 37 Pyle boom inaccuracy FAS +815 218201 37 Saxony slaughter rules FAS +816 218202 37 serializations Sabine juveniles FAS +817 218203 37 Peruvian handy comprised W +818 218204 37 taxonomically rural investigations +819 218205 37 kingdom organizer stabilizes A +820 218301 37 stint shipyard seminaries FAS +821 218302 37 Sault civics Hunter A +822 218401 37 faithful inaccuracy sporty FAS +823 218402 37 Ganymede rules test FAS +824 218403 37 tidiness juveniles weasels +825 218404 37 gainful comprised CERN +826 218407 37 contrary investigations tempering +827 218408 37 Tipperary stabilizes afore FAS +828 218409 37 tropics seminaries Galatean +829 218410 37 theorizers Hunter techniques W +830 226001 37 renew sporty error +831 226002 37 already test veranda +832 226003 37 terminal weasels severely +833 226004 37 Hegelian CERN Cassites FAS +834 226005 37 hypothesizer tempering forthcoming +835 226006 37 warningly afore guides +836 226007 37 journalizing Galatean vanish FAS +837 226008 37 nested techniques lied A +838 226203 37 Lars error sawtooth FAS +839 226204 37 saplings veranda fated FAS +840 226205 37 foothill severely gradually +841 226206 37 labeled Cassites widens +842 226207 37 imperiously forthcoming preclude +843 226208 37 reporters guides Jobrel +844 226209 37 furnishings vanish hooker +845 226210 37 precipitable lied rainstorm +846 226211 37 discounts sawtooth disconnects +847 228001 37 excises fated cruelty +848 228004 37 Stalin gradually exponentials A +849 228005 37 despot widens affective A +850 228006 37 ripeness preclude arteries +851 228007 37 Arabia Jobrel Crosby FAS +852 228008 37 unruly hooker acquaint +853 228009 37 mournfulness rainstorm evenhandedly +854 228101 37 boom disconnects percentage +855 228108 37 slaughter cruelty disobedience +856 228109 37 Sabine exponentials humility +857 228110 37 handy affective gleaning A +858 228111 37 rural arteries petted A +859 228112 37 organizer Crosby bloater A +860 228113 37 shipyard acquaint minion A +861 228114 37 civics evenhandedly marginal A +862 228115 37 inaccuracy percentage apiary A +863 228116 37 rules disobedience measures +864 228117 37 juveniles humility precaution +865 228118 37 comprised gleaning repelled +866 228119 37 investigations petted primary FAS +867 228120 37 stabilizes bloater coverings +868 228121 37 seminaries minion Artemia A +869 228122 37 Hunter marginal navigate +870 228201 37 sporty apiary spatial +871 228206 37 test measures Gurkha +872 228207 37 weasels precaution meanwhile A +873 228208 37 CERN repelled Melinda A +874 228209 37 tempering primary Butterfield +875 228210 37 afore coverings Aldrich A +876 228211 37 Galatean Artemia previewing A +877 228212 37 techniques navigate glut A +878 228213 37 error spatial unaffected +879 228214 37 veranda Gurkha inmate +880 228301 37 severely meanwhile mineral +881 228305 37 Cassites Melinda impending A +882 228306 37 forthcoming Butterfield meditation A +883 228307 37 guides Aldrich ideas +884 228308 37 vanish previewing miniaturizes W +885 228309 37 lied glut lewdly +886 228310 37 sawtooth unaffected title +887 228311 37 fated inmate youthfulness +888 228312 37 gradually mineral creak FAS +889 228313 37 widens impending Chippewa +890 228314 37 preclude meditation clamored +891 228401 65 Jobrel ideas freezes +892 228402 65 hooker miniaturizes forgivably FAS +893 228403 65 rainstorm lewdly reduce FAS +894 228404 65 disconnects title McGovern W +895 228405 65 cruelty youthfulness Nazis W +896 228406 65 exponentials creak epistle W +897 228407 65 affective Chippewa socializes W +898 228408 65 arteries clamored conceptions +899 228409 65 Crosby freezes Kevin +900 228410 65 acquaint forgivably uncovering +901 230301 37 evenhandedly reduce chews FAS +902 230302 37 percentage McGovern appendixes FAS +903 230303 37 disobedience Nazis raining +904 018062 37 humility epistle infest +905 230501 37 gleaning socializes compartment +906 230502 37 petted conceptions minting +907 230503 37 bloater Kevin ducks +908 230504 37 minion uncovering roped A +909 230505 37 marginal chews waltz +910 230506 37 apiary appendixes Lillian +911 230507 37 measures raining repressions A +912 230508 37 precaution infest chillingly +913 230509 37 repelled compartment noncritical +914 230901 37 primary minting lithograph +915 230902 37 coverings ducks spongers +916 230903 37 Artemia roped parenthood +917 230904 37 navigate waltz posed +918 230905 37 spatial Lillian instruments +919 230906 37 Gurkha repressions filial +920 230907 37 meanwhile chillingly fixedly +921 230908 37 Melinda noncritical relives +922 230909 37 Butterfield lithograph Pandora +923 230910 37 Aldrich spongers watering A +924 230911 37 previewing parenthood ungrateful +925 230912 37 glut posed secures +926 230913 37 unaffected instruments chastisers +927 230914 37 inmate filial icon +928 231304 37 mineral fixedly reuniting A +929 231305 37 impending relives imagining A +930 231306 37 meditation Pandora abiding A +931 231307 37 ideas watering omnisciently +932 231308 37 miniaturizes ungrateful Britannic +933 231309 37 lewdly secures scholastics A +934 231310 37 title chastisers mechanics A +935 231311 37 youthfulness icon humidly A +936 231312 37 creak reuniting masterpiece +937 231313 37 Chippewa imagining however +938 231314 37 clamored abiding Mendelian +939 231315 37 freezes omnisciently jarred +940 232102 37 forgivably Britannic scolds +941 232103 37 reduce scholastics infatuate +942 232104 37 McGovern mechanics willed A +943 232105 37 Nazis humidly joyfully +944 232106 37 epistle masterpiece Microsoft +945 232107 37 socializes however fibrosities +946 232108 37 conceptions Mendelian Baltimorean +947 232601 37 Kevin jarred equestrian +948 232602 37 uncovering scolds Goodrich +949 232603 37 chews infatuate apish A +950 232605 37 appendixes willed Adlerian +5950 1232605 37 appendixes willed Adlerian +5951 1232606 37 appendixes willed Adlerian +5952 1232607 37 appendixes willed Adlerian +5953 1232608 37 appendixes willed Adlerian +5954 1232609 37 appendixes willed Adlerian +951 232606 37 raining joyfully Tropez +952 232607 37 infest Microsoft nouns +953 232608 37 compartment fibrosities distracting +954 232609 37 minting Baltimorean mutton +955 236104 37 ducks equestrian bridgeable A +956 236105 37 roped Goodrich stickers A +957 236106 37 waltz apish transcontinental A +958 236107 37 Lillian Adlerian amateurish +959 236108 37 repressions Tropez Gandhian +960 236109 37 chillingly nouns stratified +961 236110 37 noncritical distracting chamberlains +962 236111 37 lithograph mutton creditably +963 236112 37 spongers bridgeable philosophic +964 236113 37 parenthood stickers ores +965 238005 37 posed transcontinental Carleton +966 238006 37 instruments amateurish tape A +967 238007 37 filial Gandhian afloat A +968 238008 37 fixedly stratified goodness A +969 238009 37 relives chamberlains welcoming +970 238010 37 Pandora creditably Pinsky FAS +971 238011 37 watering philosophic halting +972 238012 37 ungrateful ores bibliography +973 238013 37 secures Carleton decoding +974 240401 41 chastisers tape variance A +975 240402 41 icon afloat allowed A +976 240901 41 reuniting goodness dire A +977 240902 41 imagining welcoming dub A +978 241801 41 abiding Pinsky poisoning +979 242101 41 omnisciently halting Iraqis A +980 242102 41 Britannic bibliography heaving +981 242201 41 scholastics decoding population A +982 242202 41 mechanics variance bomb A +983 242501 41 humidly allowed Majorca A +984 242502 41 masterpiece dire Gershwins +985 246201 41 however dub explorers +986 246202 41 Mendelian poisoning libretto A +987 246203 41 jarred Iraqis occurred +988 246204 41 scolds heaving Lagos +989 246205 41 infatuate population rats +990 246301 41 willed bomb bankruptcies A +991 246302 41 joyfully Majorca crying +992 248001 41 Microsoft Gershwins unexpected +993 248002 41 fibrosities explorers accessed A +994 248003 41 Baltimorean libretto colorful A +995 248004 41 equestrian occurred versatility A +996 248005 41 Goodrich Lagos cosy +997 248006 41 apish rats Darius A +998 248007 41 Adlerian bankruptcies mastering A +999 248008 41 Tropez crying Asiaticizations A +1000 248009 41 nouns unexpected offerers A +1001 248010 41 distracting accessed uncles A +1002 248011 41 mutton colorful sleepwalk +1003 248012 41 bridgeable versatility Ernestine +1004 248013 41 stickers cosy checksumming +1005 248014 41 transcontinental Darius stopped +1006 248015 41 amateurish mastering sicker +1007 248016 41 Gandhian Asiaticizations Italianization +1008 248017 41 stratified offerers alphabetic +1009 248018 41 chamberlains uncles pharmaceutic +1010 248019 41 creditably sleepwalk creator +1011 248020 41 philosophic Ernestine chess +1012 248021 41 ores checksumming charcoal +1013 248101 41 Carleton stopped Epiphany A +1014 248102 41 tape sicker bulldozes A +1015 248201 41 afloat Italianization Pygmalion A +1016 248202 41 goodness alphabetic caressing A +1017 248203 41 welcoming pharmaceutic Palestine A +1018 248204 41 Pinsky creator regimented A +1019 248205 41 halting chess scars A +1020 248206 41 bibliography charcoal realest A +1021 248207 41 decoding Epiphany diffusing A +1022 248208 41 variance bulldozes clubroom A +1023 248209 41 allowed Pygmalion Blythe A +1024 248210 41 dire caressing ahead +1025 248211 50 dub Palestine reviver +1026 250501 34 poisoning regimented retransmitting A +1027 250502 34 Iraqis scars landslide +1028 250503 34 heaving realest Eiffel +1029 250504 34 population diffusing absentee +1030 250505 34 bomb clubroom aye +1031 250601 34 Majorca Blythe forked A +1032 250602 34 Gershwins ahead Peruvianizes +1033 250603 34 explorers reviver clerked +1034 250604 34 libretto retransmitting tutor +1035 250605 34 occurred landslide boulevard +1036 251001 34 Lagos Eiffel shuttered +1037 251002 34 rats absentee quotes A +1038 251003 34 bankruptcies aye Caltech +1039 251004 34 crying forked Mossberg +1040 251005 34 unexpected Peruvianizes kept +1041 251301 34 accessed clerked roundly +1042 251302 34 colorful tutor features A +1043 251303 34 versatility boulevard imaginable A +1044 251304 34 cosy shuttered controller +1045 251305 34 Darius quotes racial +1046 251401 34 mastering Caltech uprisings A +1047 251402 34 Asiaticizations Mossberg narrowed A +1048 251403 34 offerers kept cannot A +1049 251404 34 uncles roundly vest +1050 251405 34 sleepwalk features famine +1051 251406 34 Ernestine imaginable sugars +1052 251801 34 checksumming controller exterminated A +1053 251802 34 stopped racial belays +1054 252101 34 sicker uprisings Hodges A +1055 252102 34 Italianization narrowed translatable +1056 252301 34 alphabetic cannot duality A +1057 252302 34 pharmaceutic vest recording A +1058 252303 34 creator famine rouses A +1059 252304 34 chess sugars poison +1060 252305 34 charcoal exterminated attitude +1061 252306 34 Epiphany belays dusted +1062 252307 34 bulldozes Hodges encompasses +1063 252308 34 Pygmalion translatable presentation +1064 252309 34 caressing duality Kantian +1065 256001 34 Palestine recording imprecision A +1066 256002 34 regimented rouses saving +1067 256003 34 scars poison maternal +1068 256004 34 realest attitude hewed +1069 256005 34 diffusing dusted kerosene +1070 258001 34 clubroom encompasses Cubans +1071 258002 34 Blythe presentation photographers +1072 258003 34 ahead Kantian nymph A +1073 258004 34 reviver imprecision bedlam A +1074 258005 34 retransmitting saving north A +1075 258006 34 landslide maternal Schoenberg A +1076 258007 34 Eiffel hewed botany A +1077 258008 34 absentee kerosene curs +1078 258009 34 aye Cubans solidification +1079 258010 34 forked photographers inheritresses +1080 258011 34 Peruvianizes nymph stiller +1081 258101 68 clerked bedlam t1 A +1082 258102 68 tutor north suite A +1083 258103 34 boulevard Schoenberg ransomer +1084 258104 68 shuttered botany Willy +1085 258105 68 quotes curs Rena A +1086 258106 68 Caltech solidification Seattle A +1087 258107 68 Mossberg inheritresses relaxes A +1088 258108 68 kept stiller exclaim +1089 258109 68 roundly t1 implicated A +1090 258110 68 features suite distinguish +1091 258111 68 imaginable ransomer assayed +1092 258112 68 controller Willy homeowner +1093 258113 68 racial Rena and +1094 258201 34 uprisings Seattle stealth +1095 258202 34 narrowed relaxes coinciding A +1096 258203 34 cannot exclaim founder A +1097 258204 34 vest implicated environing +1098 258205 34 famine distinguish jewelry +1099 258301 34 sugars assayed lemons A +1100 258401 34 exterminated homeowner brokenness A +1101 258402 34 belays and bedpost A +1102 258403 34 Hodges stealth assurers A +1103 258404 34 translatable coinciding annoyers +1104 258405 34 duality founder affixed +1105 258406 34 recording environing warbling +1106 258407 34 rouses jewelry seriously +1107 228123 37 poison lemons boasted +1108 250606 34 attitude brokenness Chantilly +1109 208405 37 dusted bedpost Iranizes +1110 212101 37 encompasses assurers violinist +1111 218206 37 presentation annoyers extramarital +1112 150401 37 Kantian affixed spates +1113 248212 41 imprecision warbling cloakroom +1114 128026 00 saving seriously gazer +1115 128024 00 maternal boasted hand +1116 128027 00 hewed Chantilly tucked +1117 128025 00 kerosene Iranizes gems +1118 128109 00 Cubans violinist clinker +1119 128705 00 photographers extramarital refiner +1120 126303 00 nymph spates callus +1121 128308 00 bedlam cloakroom leopards +1122 128204 00 north gazer comfortingly +1123 128205 00 Schoenberg hand generically +1124 128206 00 botany tucked getters +1125 128207 00 curs gems sexually +1126 118205 00 solidification clinker spear +1127 116801 00 inheritresses refiner serums +1128 116803 00 stiller callus Italianization +1129 116804 00 t1 leopards attendants +1130 116802 00 suite comfortingly spies +1131 128605 00 ransomer generically Anthony +1132 118308 00 Willy getters planar +1133 113702 00 Rena sexually cupped +1134 113703 00 Seattle spear cleanser +1135 112103 00 relaxes serums commuters +1136 118009 00 exclaim Italianization honeysuckle +5136 1118009 00 exclaim Italianization honeysuckle +1137 138011 00 implicated attendants orphanage +1138 138010 00 distinguish spies skies +1139 138012 00 assayed Anthony crushers +1140 068304 00 homeowner planar Puritan +1141 078009 00 and cupped squeezer +1142 108013 00 stealth cleanser bruises +1143 084004 00 coinciding commuters bonfire +1144 083402 00 founder honeysuckle Colombo +1145 084003 00 environing orphanage nondecreasing +1146 088504 00 jewelry skies innocents +1147 088005 00 lemons crushers masked +1148 088007 00 brokenness Puritan file +1149 088006 00 bedpost squeezer brush +1150 148025 00 assurers bruises mutilate +1151 148024 00 annoyers bonfire mommy +1152 138305 00 affixed Colombo bulkheads +1153 138306 00 warbling nondecreasing undeclared +1154 152701 00 seriously innocents displacements +1155 148505 00 boasted masked nieces +1156 158003 00 Chantilly file coeducation +1157 156201 00 Iranizes brush brassy +1158 156202 00 violinist mutilate authenticator +1159 158307 00 extramarital mommy Washoe +1160 158402 00 spates bulkheads penny +1161 158401 00 cloakroom undeclared Flagler +1162 068013 00 gazer displacements stoned +1163 068012 00 hand nieces cranes +1164 068203 00 tucked coeducation masterful +1165 088205 00 gems brassy biracial +1166 068704 00 clinker authenticator steamships +1167 068604 00 refiner Washoe windmills +1168 158502 00 callus penny exploit +1169 123103 00 leopards Flagler riverfront +1170 148026 00 comfortingly stoned sisterly +1171 123302 00 generically cranes sharpshoot +1172 076503 00 getters masterful mittens +1173 126304 00 sexually biracial interdependency +1174 068306 00 spear steamships policy +1175 143504 00 serums windmills unleashing +1176 160201 00 Italianization exploit pretenders +1177 148028 00 attendants riverfront overstatements +1178 148027 00 spies sisterly birthed +1179 143505 00 Anthony sharpshoot opportunism +1180 108014 00 planar mittens showroom +1181 076104 00 cupped interdependency compromisingly +1182 078106 00 cleanser policy Medicare +1183 126102 00 commuters unleashing corresponds +1184 128029 00 honeysuckle pretenders hardware +1185 128028 00 orphanage overstatements implant +1186 018410 00 skies birthed Alicia +1187 128110 00 crushers opportunism requesting +1188 148506 00 Puritan showroom produced +1189 123303 00 squeezer compromisingly criticizes +1190 123304 00 bruises Medicare backer +1191 068504 00 bonfire corresponds positively +1192 068305 00 Colombo hardware colicky +1193 000000 00 nondecreasing implant thrillingly +1 000001 00 Omaha teethe neat +2 011401 37 breaking dreaded Steinberg W +3 011402 37 Romans scholastics jarring +4 011403 37 intercepted audiology tinily +2 011401 37 breaking dreaded Steinberg W +3 011402 37 Romans scholastics jarring +4 011403 37 intercepted audiology tinily +1 000001 00 Omaha teethe neat +2 011401 37 breaking dreaded Steinberg W +3 011402 37 Romans scholastics jarring +4 011403 37 intercepted audiology tinily +2 011401 37 breaking dreaded Steinberg W +3 011402 37 Romans scholastics jarring +4 011403 37 intercepted audiology tinily +4 011403 37 intercepted audiology tinily ALTER TABLE t2 DROP COLUMN fld6; SHOW CREATE TABLE t2; Table Create Table diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 68e3192e8a4..535402c2e13 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1344,9 +1344,11 @@ CHECK TABLE t2; SELECT * FROM t2; -# Just test syntax, we will never know if the output is right or wrong -# Must be the last test +# We won't know exactly about what is going on internally, +# but we will see if the row makes it in!! INSERT DELAYED INTO t2 VALUES (4,011403,37,'intercepted','audiology','tinily',''); +FLUSH TABLE t2; +SELECT * FROM t2; # Adding test for alter table ALTER TABLE t2 DROP COLUMN fld6; diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc index b6ae7a4b75f..8ed16949edd 100644 --- a/sql/ha_archive.cc +++ b/sql/ha_archive.cc @@ -126,10 +126,10 @@ static HASH archive_open_tables; #define ARN ".ARN" // Files used during an optimize call #define ARM ".ARM" // Meta file /* - uchar + uchar + ulonglong + ulonglong + ulonglong + uchar + uchar + uchar + ulonglong + ulonglong + ulonglong + ulonglong + uchar */ #define META_BUFFER_SIZE sizeof(uchar) + sizeof(uchar) + sizeof(ulonglong) \ - + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(uchar) + + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(ulonglong) + sizeof(uchar) /* uchar + uchar @@ -313,7 +313,8 @@ error: *rows will contain the current number of rows in the data file upon success. */ int ha_archive::read_meta_file(File meta_file, ha_rows *rows, - ulonglong *auto_increment) + ulonglong *auto_increment, + ulonglong *forced_flushes) { uchar meta_buffer[META_BUFFER_SIZE]; uchar *ptr= meta_buffer; @@ -336,12 +337,15 @@ int ha_archive::read_meta_file(File meta_file, ha_rows *rows, ptr+= sizeof(ulonglong); // Move past check_point *auto_increment= uint8korr(ptr); ptr+= sizeof(ulonglong); // Move past auto_increment + *forced_flushes= uint8korr(ptr); + ptr+= sizeof(ulonglong); // Move past forced_flush DBUG_PRINT("ha_archive::read_meta_file", ("Check %d", (uint)meta_buffer[0])); DBUG_PRINT("ha_archive::read_meta_file", ("Version %d", (uint)meta_buffer[1])); DBUG_PRINT("ha_archive::read_meta_file", ("Rows %llu", *rows)); DBUG_PRINT("ha_archive::read_meta_file", ("Checkpoint %llu", check_point)); DBUG_PRINT("ha_archive::read_meta_file", ("Auto-Increment %llu", *auto_increment)); + DBUG_PRINT("ha_archive::read_meta_file", ("Forced Flushes %llu", *forced_flushes)); DBUG_PRINT("ha_archive::read_meta_file", ("Dirty %d", (int)(*ptr))); if ((meta_buffer[0] != (uchar)ARCHIVE_CHECK_HEADER) || @@ -359,7 +363,9 @@ int ha_archive::read_meta_file(File meta_file, ha_rows *rows, Upon ::open() we set to dirty, and upon ::close() we set to clean. */ int ha_archive::write_meta_file(File meta_file, ha_rows rows, - ulonglong auto_increment, bool dirty) + ulonglong auto_increment, + ulonglong forced_flushes, + bool dirty) { uchar meta_buffer[META_BUFFER_SIZE]; uchar *ptr= meta_buffer; @@ -377,6 +383,8 @@ int ha_archive::write_meta_file(File meta_file, ha_rows rows, ptr += sizeof(ulonglong); int8store(ptr, auto_increment); ptr += sizeof(ulonglong); + int8store(ptr, forced_flushes); + ptr += sizeof(ulonglong); *ptr= (uchar)dirty; DBUG_PRINT("ha_archive::write_meta_file", ("Check %d", (uint)ARCHIVE_CHECK_HEADER)); @@ -386,6 +394,8 @@ int ha_archive::write_meta_file(File meta_file, ha_rows rows, DBUG_PRINT("ha_archive::write_meta_file", ("Checkpoint %llu", check_point)); DBUG_PRINT("ha_archive::write_meta_file", ("Auto Increment %llu", auto_increment)); + DBUG_PRINT("ha_archive::write_meta_file", ("Forced Flushes %llu", + forced_flushes)); DBUG_PRINT("ha_archive::write_meta_file", ("Dirty %d", (uint)dirty)); VOID(my_seek(meta_file, 0, MY_SEEK_SET, MYF(0))); @@ -451,11 +461,14 @@ ARCHIVE_SHARE *ha_archive::get_share(const char *table_name, leave it up to the user to fix. */ if (read_meta_file(share->meta_file, &share->rows_recorded, - &share->auto_increment_value)) + &share->auto_increment_value, + &share->forced_flushes)) share->crashed= TRUE; else (void)write_meta_file(share->meta_file, share->rows_recorded, - share->auto_increment_value, TRUE); + share->auto_increment_value, + share->forced_flushes, + TRUE); /* It is expensive to open and close the data files and since you can't have a gzip file that can be both read and written we keep a writer open @@ -500,12 +513,18 @@ int ha_archive::free_share(ARCHIVE_SHARE *share) hash_delete(&archive_open_tables, (byte*) share); thr_lock_delete(&share->lock); VOID(pthread_mutex_destroy(&share->mutex)); - if (share->crashed) - (void)write_meta_file(share->meta_file, share->rows_recorded, - share->auto_increment_value, TRUE); - else - (void)write_meta_file(share->meta_file, share->rows_recorded, - share->auto_increment_value, FALSE); + /* + We need to make sure we don't reset the crashed state. + If we open a crashed file, wee need to close it as crashed unless + it has been repaired. + Since we will close the data down after this, we go on and count + the flush on close; + */ + share->forced_flushes++; + (void)write_meta_file(share->meta_file, share->rows_recorded, + share->auto_increment_value, + share->forced_flushes, + share->crashed ? TRUE :FALSE); if (azclose(&(share->archive_write))) rc= 1; if (my_close(share->meta_file, MYF(0))) @@ -657,7 +676,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, } } - write_meta_file(create_file, 0, auto_increment_value, FALSE); + write_meta_file(create_file, 0, auto_increment_value, 0, FALSE); my_close(create_file,MYF(0)); /* @@ -800,6 +819,7 @@ int ha_archive::write_row(byte *buf) data */ azflush(&(share->archive_write), Z_SYNC_FLUSH); + share->forced_flushes++; /* Set the position of the local read thread to the beginning postion. */ @@ -897,6 +917,7 @@ int ha_archive::index_read_idx(byte *buf, uint index, const byte *key, */ pthread_mutex_lock(&share->mutex); azflush(&(share->archive_write), Z_SYNC_FLUSH); + share->forced_flushes++; pthread_mutex_unlock(&share->mutex); /* @@ -974,6 +995,7 @@ int ha_archive::rnd_init(bool scan) { DBUG_PRINT("info", ("archive flushing out rows for scan")); azflush(&(share->archive_write), Z_SYNC_FLUSH); + share->forced_flushes++; share->dirty= FALSE; } pthread_mutex_unlock(&share->mutex); @@ -1149,6 +1171,7 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) /* Flush any waiting data */ azflush(&(share->archive_write), Z_SYNC_FLUSH); + share->forced_flushes++; /* Lets create a file to contain the new data */ fn_format(writer_filename, share->table_name, "", ARN, @@ -1233,13 +1256,15 @@ int ha_archive::optimize(THD* thd, HA_CHECK_OPT* check_opt) goto error; } - while ((read= azread(&archive, block, IO_SIZE))) + while ((read= azread(&archive, block, IO_SIZE)) > 0) azwrite(&writer, block, read); } azclose(&writer); share->dirty= FALSE; + share->forced_flushes= 0; azclose(&(share->archive_write)); + DBUG_PRINT("info", ("Reopening archive data file")); if (!(azopen(&(share->archive_write), share->data_file_name, O_WRONLY|O_APPEND|O_BINARY))) { @@ -1421,6 +1446,7 @@ int ha_archive::check(THD* thd, HA_CHECK_OPT* check_opt) thd->proc_info= "Checking table"; /* Flush any waiting data */ azflush(&(share->archive_write), Z_SYNC_FLUSH); + share->forced_flushes++; /* First we create a buffer that we can use for reading rows, and can pass diff --git a/sql/ha_archive.h b/sql/ha_archive.h index 7766ae0d2e9..9b351b7e8da 100644 --- a/sql/ha_archive.h +++ b/sql/ha_archive.h @@ -39,6 +39,8 @@ typedef struct st_archive_share { bool crashed; /* Meta file is crashed */ ha_rows rows_recorded; /* Number of rows in tables */ ulonglong auto_increment_value; + ulonglong forced_flushes; + ulonglong mean_rec_length; } ARCHIVE_SHARE; /* @@ -98,9 +100,13 @@ public: int rnd_next(byte *buf); int rnd_pos(byte * buf, byte *pos); int get_row(azio_stream *file_to_read, byte *buf); - int read_meta_file(File meta_file, ha_rows *rows, ulonglong *auto_increment); + int read_meta_file(File meta_file, ha_rows *rows, + ulonglong *auto_increment, + ulonglong *forced_flushes); int write_meta_file(File meta_file, ha_rows rows, - ulonglong auto_increment, bool dirty); + ulonglong auto_increment, + ulonglong forced_flushes, + bool dirty); ARCHIVE_SHARE *get_share(const char *table_name, TABLE *table, int *rc); int free_share(ARCHIVE_SHARE *share); bool auto_repair() const { return 1; } // For the moment we just do this