List:Commits« Previous MessageNext Message »
From:Alfranio Correia Date:May 15 2009 10:15am
Subject:bzr push into mysql-6.0-rpl branch (alfranio.correia:2851 to 2852)
View as plain text  
 2852 Alfranio Correia	2009-05-15
      vWL#4828 Augment DBUG_ENTER/DBUG_EXIT to crash MySQL in different functions
      
      The assessment of the replication code in the presence of faults is extremely
      import to increase reliability. In particular, one needs to know if servers
      will either correctly recovery or print out appropriate error messages thus
      avoiding unexpected problems in a production environment.
      
      In order to accomplish this, the current patch changes the debug macros
      already provided in the source code and introduces three new macros that
      allows fault-injection, specifically crashes, while entering or exiting
      a function or method. For instance, to crash a server while returning
      from the init_slave function (see module sql/slave.cc), one needs to do
      what follows:
      
      1 - Modify the source replacing DBUG_RETURN by DBUG_CRASH_RETURN;
      
        DBUG_CRASH_RETURN(0);
      
      2 - Use the debug variable to activate dbug instructions:
      
        SET SESSION debug="+d,init_slave_crash_return";
      
      The new macros are briefly described below:
      
      DBUG_CRASH_ENTER (function) is equivalent to DBUG_ENTER which registers the
      beginning of a function but in addition to it allows for crashing the server
      while entering the function if the appropriate dbug instruction is activate.
      In this case, the dbug instruction should be "+d,function_crash_enter".
      
      DBUG_CRASH_RETURN (value) is equivalent to DBUG_RETURN which notifies the
      end of a function but in addition to it allows for crashing the server
      while returning from the function if the appropriate dbug instruction is
      activate. In this case, the dbug instruction should be
      "+d,function_crash_return". Note that "function" should be the same string
      used by either the DBUG_ENTER or DBUG_CRASH_ENTER.
      
      DBUG_CRASH_VOID_RETURN (value) is equivalent to DBUG_VOID_RETURN which
      notifies the end of a function but in addition to it allows for crashing
      the server while returning from the function if the appropriate dbug
      instruction is activate. In this case, the dbug instruction should be
      "+d,function_crash_return". Note that "function" should be the same string
      used by either the DBUG_ENTER or DBUG_CRASH_ENTER.
      
      To inject other faults, for instance, wrong return values, one should rely
      on the macros already available. The current patch also removes a set of
      macros that were either not being used or were redundant as other macros
      could be used to provide the same feature. In the future, we also consider
      dynamic instrumentation of the code.
     @ dbug/dbug.c
        1 - _db_keywords_ that concatenates two strings and checks if the result
        string is activated by the dbug instructions. The first string is the name
        of the function and the second string is either "crash_enter" or "crash_return".
        This is used by the new macros: DBUG_CRASH_ENTER, DBUG_CRASH_VOID_RETURN and
        DBUG_CRASH_RETURN.
        
        2 - _db_get_func_ returns the name of the current function. This is used by
        the DBUG_CRASH_VOID_RETURN and DBUG_CRASH_RETURN to automatically figure out
        which is the function they are referencing to.
     @ include/my_dbug.h
        Defines the new macros.
     @ sql/mysql_priv.h
        Removes a set of unused macros.
     @ sql/sql_class.cc
        Removes a set of unused macros.
     @ sql/sql_class.h
        Removes a set of unused macros.
     @ sql/sql_partition.cc
        Localy redefines a macro that was removed to avoid changing the module 
        in several places.

    modified:
      dbug/dbug.c
      include/my_dbug.h
      sql/mysql_priv.h
      sql/sql_class.cc
      sql/sql_class.h
      sql/sql_partition.cc
 2851 Luis Soares	2009-05-14 [merge]
      merge: 6.0-rpl bug branch --> 6.0-rpl up-to-date.

    added:
      mysql-test/extra/rpl_tests/rpl_show_relaylog_events.inc
      mysql-test/include/show_relaylog_events.inc
      mysql-test/suite/rpl/r/rpl_row_show_relaylog_events.result
      mysql-test/suite/rpl/r/rpl_stm_mix_show_relaylog_events.result
      mysql-test/suite/rpl/t/rpl_row_show_relaylog_events.test
      mysql-test/suite/rpl/t/rpl_stm_mix_show_relaylog_events.test
    modified:
      mysql-test/include/show_binlog_events.inc
      sql/lex.h
      sql/mysqld.cc
      sql/sp_head.cc
      sql/sql_lex.h
      sql/sql_parse.cc
      sql/sql_repl.cc
      sql/sql_yacc.yy
=== modified file 'dbug/dbug.c'
--- a/dbug/dbug.c	2009-03-25 16:51:28 +0000
+++ b/dbug/dbug.c	2009-05-15 10:06:26 +0000
@@ -1836,6 +1836,27 @@ BOOLEAN _db_keyword_(CODE_STATE *cs, con
 /*
  *  FUNCTION
  *
+ *      _db_keywords_    test keyword formed by a set of strings for member
+ *                       of keyword list
+ *
+ *  DESCRIPTION
+ *
+ *      This function is similar to _db_keyword but receives a set of strings to
+ *      be concatenated in order to make the keyword to be compared.
+ */
+
+BOOLEAN _db_keywords_(CODE_STATE *cs, int strict, char *function, char *type)
+{
+  char dest[_DBUG_MAX_FUNC_NAME_ + 1];
+
+  strxnmov(dest, _DBUG_MAX_FUNC_NAME_, function, type, NULL);
+
+  return _db_keyword_(cs, dest, strict);
+}
+
+/*
+ *  FUNCTION
+ *
  *      Indent    indent a line to the given indentation level
  *
  *  SYNOPSIS
@@ -2460,6 +2481,13 @@ void _db_unlock_file_()
   pthread_mutex_unlock(&THR_LOCK_dbug);
 }
 
+const char* _db_get_func_(void)
+{
+  CODE_STATE *cs;
+  get_code_state_or_return NULL;
+  return cs->func;
+}
+
 /*
  * Here we need the definitions of the clock routine.  Add your
  * own for whatever system that you have.

=== modified file 'include/my_dbug.h'
--- a/include/my_dbug.h	2008-12-10 17:04:38 +0000
+++ b/include/my_dbug.h	2009-05-15 10:06:26 +0000
@@ -31,6 +31,7 @@ struct _db_stack_frame_ {
 struct  _db_code_state_;
 extern  my_bool _dbug_on_;
 extern  my_bool _db_keyword_(struct _db_code_state_ *, const char *, int);
+extern  my_bool _db_keywords_(struct _db_code_state_ *, int, char *, char *);
 extern  int _db_explain_(struct _db_code_state_ *cs, char *buf, size_t len);
 extern  int _db_explain_init_(char *buf, size_t len);
 extern	int _db_is_pushed_(void);
@@ -54,6 +55,7 @@ extern  void _db_lock_file_(void);
 extern  void _db_unlock_file_(void);
 extern  FILE *_db_fp_(void);
 extern  void _db_flush_();
+extern  const char* _db_get_func_(void);
 
 #define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_; \
         _db_enter_ (a,__FILE__,__LINE__,&_db_stack_frame_)
@@ -101,6 +103,20 @@ extern  void _db_flush_();
                      (void)_CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR),\
                      _exit(3))
 #endif
+#define _DBUG_MAX_FUNC_NAME_ 255
+#define DBUG_CHECK_CRASH(func, op) \
+        do { \
+          if (_db_keywords_(0, 0, (func), (op))) \
+            { (_db_flush_(), abort()); } \
+        } while (0)
+#define DBUG_CRASH_ENTER(func) \
+  DBUG_ENTER(func); DBUG_CHECK_CRASH(func, "_crash_enter")
+#define DBUG_CRASH_RETURN(val) \
+  do {DBUG_CHECK_CRASH(_db_get_func_(), "_crash_return"); \
+    DBUG_RETURN(val);} while(0)
+#define DBUG_CRASH_VOID_RETURN \
+  do {DBUG_CHECK_CRASH (_db_get_func_(), "_crash_return"); \
+    DBUG_VOID_RETURN;} while(0)
 
 #else                                           /* No debugger */
 
@@ -132,6 +148,9 @@ extern  void _db_flush_();
 #define DEBUGGER_ON                     do { } while(0)
 #define IF_DBUG(A)
 #define DBUG_ABORT()                    abort()
+#define DBUG_CRASH_ENTER(func)
+#define DBUG_CRASH_RETURN(val)          do { return(val); } while(0)
+#define DBUG_CRASH_VOID_RETURN          do { return; } while(0)
 
 #endif
 #ifdef  __cplusplus

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2009-05-07 20:48:24 +0000
+++ b/sql/mysql_priv.h	2009-05-15 10:06:26 +0000
@@ -977,100 +977,6 @@ struct Query_cache_query_flags
 #define query_cache_is_cacheable_query(L) 0
 #endif /*HAVE_QUERY_CACHE*/
 
-/*
-  Error injector Macros to enable easy testing of recovery after failures
-  in various error cases.
-*/
-#ifndef ERROR_INJECT_SUPPORT
-
-#define ERROR_INJECT(x) 0
-#define ERROR_INJECT_ACTION(x,action) 0
-#define ERROR_INJECT_CRASH(x) 0
-#define ERROR_INJECT_VALUE(x) 0
-#define ERROR_INJECT_VALUE_ACTION(x,action) 0
-#define ERROR_INJECT_VALUE_CRASH(x) 0
-#define SET_ERROR_INJECT_VALUE(x)
-
-#else
-
-inline bool check_and_unset_keyword(const char *dbug_str)
-{
-  const char *extra_str= "-d,";
-  char total_str[200];
-  if (_db_keyword_ (0, dbug_str, 1))
-  {
-    strxmov(total_str, extra_str, dbug_str, NullS);
-    DBUG_SET(total_str);
-    return 1;
-  }
-  return 0;
-}
-
-
-inline bool
-check_and_unset_inject_value(int value)
-{
-  THD *thd= current_thd;
-  if (thd->error_inject_value == (uint)value)
-  {
-    thd->error_inject_value= 0;
-    return 1;
-  }
-  return 0;
-}
-
-/*
-  ERROR INJECT MODULE:
-  --------------------
-  These macros are used to insert macros from the application code.
-  The event that activates those error injections can be activated
-  from SQL by using:
-  SET SESSION dbug=+d,code;
-
-  After the error has been injected, the macros will automatically
-  remove the debug code, thus similar to using:
-  SET SESSION dbug=-d,code
-  from SQL.
-
-  ERROR_INJECT_CRASH will inject a crash of the MySQL Server if code
-  is set when macro is called. ERROR_INJECT_CRASH can be used in
-  if-statements, it will always return FALSE unless of course it
-  crashes in which case it doesn't return at all.
-
-  ERROR_INJECT_ACTION will inject the action specified in the action
-  parameter of the macro, before performing the action the code will
-  be removed such that no more events occur. ERROR_INJECT_ACTION
-  can also be used in if-statements and always returns FALSE.
-  ERROR_INJECT can be used in a normal if-statement, where the action
-  part is performed in the if-block. The macro returns TRUE if the
-  error was activated and otherwise returns FALSE. If activated the
-  code is removed.
-
-  Sometimes it is necessary to perform error inject actions as a serie
-  of events. In this case one can use one variable on the THD object.
-  Thus one sets this value by using e.g. SET_ERROR_INJECT_VALUE(100).
-  Then one can later test for it by using ERROR_INJECT_CRASH_VALUE,
-  ERROR_INJECT_ACTION_VALUE and ERROR_INJECT_VALUE. This have the same
-  behaviour as the above described macros except that they use the
-  error inject value instead of a code used by DBUG macros.
-*/
-#define SET_ERROR_INJECT_VALUE(x) \
-  current_thd->error_inject_value= (x)
-#define ERROR_INJECT_CRASH(code) \
-  DBUG_EVALUATE_IF(code, (DBUG_ABORT(), 0), 0)
-#define ERROR_INJECT_ACTION(code, action) \
-  (check_and_unset_keyword(code) ? ((action), 0) : 0)
-#define ERROR_INJECT(code) \
-  check_and_unset_keyword(code)
-#define ERROR_INJECT_VALUE(value) \
-  check_and_unset_inject_value(value)
-#define ERROR_INJECT_VALUE_ACTION(value,action) \
-  (check_and_unset_inject_value(value) ? (action) : 0)
-#define ERROR_INJECT_VALUE_CRASH(value) \
-  ERROR_INJECT_VALUE_ACTION(value, (DBUG_ABORT(), 0))
-
-#endif
-
 void write_bin_log(THD *thd, bool clear_error,
                    char const *query, ulong query_length);
 

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2009-05-12 08:58:44 +0000
+++ b/sql/sql_class.cc	2009-05-15 10:06:26 +0000
@@ -493,9 +493,6 @@ THD::THD()
   limit_found_rows= 0;
   row_count_func= -1;
   statement_id_counter= 0UL;
-#ifdef ERROR_INJECT_SUPPORT
-  error_inject_value= 0UL;
-#endif
   // Must be reset to handle error with THD's created for init of mysqld
   lex->current_select= 0;
   start_time=(time_t) 0;

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2009-05-12 08:58:44 +0000
+++ b/sql/sql_class.h	2009-05-15 10:06:26 +0000
@@ -1696,9 +1696,6 @@ public:
   query_id_t query_id;
   ulong      col_access;
 
-#ifdef ERROR_INJECT_SUPPORT
-  ulong      error_inject_value;
-#endif
   /* Statement id is thread-wide. This counter is used to generate ids */
   ulong      statement_id_counter;
   ulong	     rand_saved_seed1, rand_saved_seed2;

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2009-04-01 09:15:50 +0000
+++ b/sql/sql_partition.cc	2009-05-15 10:06:26 +0000
@@ -41,6 +41,10 @@
 
 #ifdef WITH_PARTITION_STORAGE_ENGINE
 #include "ha_partition.h"
+
+#define ERROR_INJECT_CRASH(code) \
+  DBUG_EVALUATE_IF(code, (DBUG_ABORT(), 0), 0)
+
 /*
   Partition related functions declarations and some static constants;
 */


Attachment: [text/bzr-bundle]
Thread
bzr push into mysql-6.0-rpl branch (alfranio.correia:2851 to 2852)Alfranio Correia15 May