List:Commits« Previous MessageNext Message »
From:Dmitry Shulga Date:October 19 2010 11:50am
Subject:bzr commit into mysql-5.1-bugteam branch (Dmitry.Shulga:3523) Bug#45445
View as plain text  
#At file:///Users/shulga/projects/mysql/5.1-bugteam-bug45445/ based on revid:georgi.kodinov@stripped

 3523 Dmitry Shulga	2010-10-19
      Fixed bug#45445 - cannot execute procedures with thread_stack
      set to 128k.
     @ mysql-test/collections/default.experimental
        Re-enabled test rpl.rpl_row_sp011.
     @ sql/sp.cc
        Added checking for stack overrun at functions db_load_routine/sp_find_routine.
     @ sql/sp_head.cc
        sp_head::execute() modified: pass constant value STACK_MIN_SIZE
        instead of 8 * STACK_MIN_SIZE  as second argument value
        in call to check_stack_overrun. Added checking for stack overrun
        at functions sp_lex_keeper::reset_lex_and_exec_core/sp_instr_stmt::execute.
     @ sql/sql_parse.cc
        check_stack_overrun modified: allocate buffer for error message
        at heap instead of stack.
        parse_sql modified: added call to check_stack_overrun() before
        parsing of sql statement.

    modified:
      mysql-test/collections/default.experimental
      sql/sp.cc
      sql/sp_head.cc
      sql/sql_parse.cc
=== modified file 'mysql-test/collections/default.experimental'
--- a/mysql-test/collections/default.experimental	2010-09-07 20:16:10 +0000
+++ b/mysql-test/collections/default.experimental	2010-10-19 11:50:05 +0000
@@ -22,7 +22,6 @@ main.outfile_loaddata @solaris          
 ndb.*                                    # joro : NDB tests marked as experimental as agreed with bochklin
 
 rpl.rpl_innodb_bug28430*  @solaris       # Bug#46029
-rpl.rpl_row_sp011         @solaris       # Joro : Bug #54138
 
 rpl_ndb.*                                # joro : NDB tests marked as experimental as agreed with bochklin
 rpl_ndb.rpl_ndb_log                      # Bug#38998

=== modified file 'sql/sp.cc'
--- a/sql/sp.cc	2010-06-11 12:52:06 +0000
+++ b/sql/sp.cc	2010-10-19 11:50:05 +0000
@@ -735,6 +735,9 @@ db_load_routine(THD *thd, int type, sp_n
 
   int ret;
 
+  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&ret))
+    return TRUE;
+
   thd->variables.sql_mode= sql_mode;
   thd->variables.select_limit= HA_POS_ERROR;
 
@@ -1413,6 +1416,9 @@ sp_find_routine(THD *thd, int type, sp_n
                        (int) name->m_name.length, name->m_name.str,
                        type, cache_only));
 
+  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&depth))
+    return NULL;
+
   if ((sp= sp_cache_lookup(cp, name)))
   {
     ulong level;

=== modified file 'sql/sp_head.cc'
--- a/sql/sp_head.cc	2010-07-19 14:30:34 +0000
+++ b/sql/sp_head.cc	2010-10-19 11:50:05 +0000
@@ -1108,8 +1108,28 @@ sp_head::execute(THD *thd)
 
   Object_creation_ctx *saved_creation_ctx;
 
-  /* Use some extra margin for possible SP recursion and functions */
-  if (check_stack_overrun(thd, 8 * STACK_MIN_SIZE, (uchar*)&old_packet))
+  /*
+    Just reporting a stack overrun error
+    (@sa check_stack_overrun()) requires stack memory for error
+    message buffer. Thus, we have to put the below check
+    relatively close to the beginning of the execution stack,
+    where available stack margin is still big. As long as the check
+    has to be fairly high up the call stack, the amount of memory
+    we "book" for has to stay fairly high as well, and hence
+    not very accurate. The number below has been calculated
+    by trial and error, and reflects the amount of memory necessary
+    to execute a single stored procedure instruction, be it either
+    an SQL statement, or, heaviest of all, a CALL, which involves
+    parsing and loading of another stored procedure into the cache
+    (@sa db_load_routine() and Bug#10100).
+    At the time of measuring, a recursive SP invocation required
+    3232 bytes of stack on 32 bit Linux, 6016 bytes on 64 bit Mac
+    and 11152 on 64 bit Solaris sparc.
+    The same with db_load_routine() required circa 7k bytes and
+    14k bytes accordingly. Hence, here we book the stack with some
+    reasonable margin.
+  */
+  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&old_packet))
     DBUG_RETURN(TRUE);
 
   /* init per-instruction memroot */
@@ -2730,6 +2750,9 @@ sp_lex_keeper::reset_lex_and_exec_core(T
     It's merged with the saved parent's value at the exit of this func.
   */
   bool parent_modified_non_trans_table= thd->transaction.stmt.modified_non_trans_table;
+  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&parent_modified_non_trans_table))
+    DBUG_RETURN(TRUE);
+
   thd->transaction.stmt.modified_non_trans_table= FALSE;
   DBUG_ASSERT(!thd->derived_tables);
   DBUG_ASSERT(thd->change_list.is_empty());
@@ -2872,6 +2895,9 @@ sp_instr_stmt::execute(THD *thd, uint *n
   DBUG_ENTER("sp_instr_stmt::execute");
   DBUG_PRINT("info", ("command: %d", m_lex_keeper.sql_command()));
 
+  if (check_stack_overrun(thd, STACK_MIN_SIZE, (uchar*)&res))
+    DBUG_RETURN(TRUE);
+
   query= thd->query();
   query_length= thd->query_length();
 #if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2010-08-18 04:56:06 +0000
+++ b/sql/sql_parse.cc	2010-10-19 11:50:05 +0000
@@ -5669,10 +5669,11 @@ bool check_stack_overrun(THD *thd, long 
   if ((stack_used=used_stack(thd->thread_stack,(char*) &stack_used)) >=
       (long) (my_thread_stack_size - margin))
   {
-    char ebuff[MYSQL_ERRMSG_SIZE];
-    my_snprintf(ebuff, sizeof(ebuff), ER(ER_STACK_OVERRUN_NEED_MORE),
+    char* ebuff= new char[MYSQL_ERRMSG_SIZE];
+    my_snprintf(ebuff, MYSQL_ERRMSG_SIZE, ER(ER_STACK_OVERRUN_NEED_MORE),
                 stack_used, my_thread_stack_size, margin);
     my_message(ER_STACK_OVERRUN_NEED_MORE, ebuff, MYF(ME_FATALERROR));
+    delete [] ebuff;
     thd->fatal_error();
     return 1;
   }
@@ -7916,6 +7917,12 @@ bool parse_sql(THD *thd,
 
   Object_creation_ctx *backup_ctx= NULL;
 
+  if (check_stack_overrun(thd, 2 * STACK_MIN_SIZE, (uchar*)&backup_ctx))
+  {
+    thd->m_parser_state= NULL;
+    return TRUE;
+  }
+
   if (creation_ctx)
     backup_ctx= creation_ctx->set_n_backup(thd);
 


Attachment: [text/bzr-bundle] bzr/dmitry.shulga@sun.com-20101019115005-e3vdie6ze7qiekrp.bundle
Thread
bzr commit into mysql-5.1-bugteam branch (Dmitry.Shulga:3523) Bug#45445Dmitry Shulga19 Oct