List:Commits« Previous MessageNext Message »
From:Chad MILLER Date:September 27 2006 5:27pm
Subject:bk commit into 5.0 tree (cmiller:1.2284) BUG#21476
View as plain text  
Below is the list of changes that have just been committed into a local
5.0 repository of cmiller. When cmiller does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2006-09-27 13:27:53-04:00, cmiller@stripped +7 -0
  Bug#21476: (Thread stack overrun not caught, causing SEGV)
  
  The STACK_MIN_SIZE is currently set to 8192, when we actually need 
  (emperically discovered) 9236 bytes to raise an fatal error, on Ubuntu 
  Dapper Drake, libc6 2.3.6-0ubuntu2, Linux kernel 2.6.15-27-686, on x86.
  
  I'm taking that as a new lower bound, plus 100B of wiggle-room for sundry
  word sizes and stack behaviors.
  
  The added test verifies in a cross-platform way that there are no gaps 
  between the space that we think we need and what we actually need to report 
  an error.
  
  DOCUMENTERS:  This also adds "let" to the mysqltest commands that evaluate
  an argument to expand variables therein.  (Only right of the "=", of course.)

  BitKeeper/etc/collapsed@stripped, 2006-09-27 10:14:03-04:00, cmiller@stripped +1 -0

  client/mysqltest.c@stripped, 2006-09-27 13:27:51-04:00, cmiller@stripped +8 -3
    Add "let" to the list of mysqltest commands that evaluates its arguments (only
    the right-hand-side of the equals-sign expression).  

  mysql-test/r/execution_constants.result@stripped, 2006-09-27 13:27:52-04:00, cmiller@stripped +12 -0
    New BitKeeper file ``mysql-test/r/execution_constants.result''

  mysql-test/r/execution_constants.result@stripped, 2006-09-27 13:27:52-04:00, cmiller@stripped +0 -0

  mysql-test/r/mysqltest.result@stripped, 2006-09-27 13:27:52-04:00, cmiller@stripped +4 -1
    Added test to show that mysqltest "let" will evaluate the RHS correctly (and 
    expand the backslash test).

  mysql-test/t/execution_constants.test@stripped, 2006-09-27 13:27:52-04:00, cmiller@stripped +61 -0
    New BitKeeper file ``mysql-test/t/execution_constants.test''

  mysql-test/t/execution_constants.test@stripped, 2006-09-27 13:27:52-04:00, cmiller@stripped +0 -0

  mysql-test/t/mysqltest.test@stripped, 2006-09-27 13:27:52-04:00, cmiller@stripped +12 -0
    Added test to show that mysqltest "let" will evaluate the RHS correctly (and 
    expand the backslash test).

  sql/mysql_priv.h@stripped, 2006-09-27 13:27:52-04:00, cmiller@stripped +12 -1
    Increase the amount we require to be available for the stack, since 
    experience told us that the previous amount was too little by at least
    1044 bytes.  

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	cmiller
# Host:	zippy.cornsilk.net
# Root:	/home/cmiller/work/mysql/bug21476/my50-bug21476

--- 1.410/sql/mysql_priv.h	2006-09-27 13:27:58 -04:00
+++ 1.411/sql/mysql_priv.h	2006-09-27 13:27:58 -04:00
@@ -131,7 +131,18 @@ MY_LOCALE *my_locale_by_name(const char 
 #define MAX_ACCEPT_RETRY	10	// Test accept this many times
 #define MAX_FIELDS_BEFORE_HASH	32
 #define USER_VARS_HASH_SIZE     16
-#define STACK_MIN_SIZE		8192	// Abort if less stack during eval.
+
+/* 
+ Value of 9236 discovered through binary search 2006-09-26 on Ubuntu Dapper
+ Drake, libc6 2.3.6-0ubuntu2, Linux kernel 2.6.15-27-686, on x86.  (Added 
+ 100 bytes as reasonable buffer against growth and other environments'
+ requirements.)
+
+ Feel free to raise this by the smallest amount you can to get the
+ "execution_constants" test to pass.
+ */
+#define STACK_MIN_SIZE		9336	// Abort if less stack during eval.  
+
 #define STACK_MIN_SIZE_FOR_OPEN 1024*80
 #define STACK_BUFF_ALLOC	256	// For stack overrun checks
 #ifndef MYSQLD_NET_RETRY_COUNT
--- New file ---
+++ mysql-test/r/execution_constants.result	06/09/27 13:27:52
CREATE TABLE `t_bug21476` (
`ID_BOARD` smallint(5) unsigned NOT NULL default '0',
`ID_MEMBER` mediumint(8) unsigned NOT NULL default '0',
`logTime` int(10) unsigned NOT NULL default '0',
`ID_MSG` mediumint(8) unsigned NOT NULL default '0',
PRIMARY KEY  (`ID_MEMBER`,`ID_BOARD`),
KEY `logTime` (`logTime`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;
INSERT INTO `t_bug21476` VALUES (2,2,1154870939,0),(1,2,1154870957,0),(2,183,1154941362,0),(2,84,1154904301,0),(1,84,1154905867,0),(2,13,1154947484,10271),(3,84,1154880549,0),(1,6,1154892183,0),(2,25,1154947581,10271),(3,25,1154904760,0),(1,25,1154947373,10271),(1,179,1154899992,0),(2,179,1154899410,0),(5,25,1154901666,0),(2,329,1154902026,0),(3,329,1154902040,0),(1,329,1154902058,0),(1,13,1154930841,0),(3,85,1154904987,0),(1,183,1154929665,0),(3,13,1154931268,0),(1,85,1154936888,0),(1,169,1154937959,0),(2,169,1154941717,0),(3,183,1154939810,0),(3,169,1154941734,0);
Assertion: mysql_errno 1436 == 1436
DROP TABLE `t_bug21476`;
End of 5.0 tests.

--- New file ---
+++ mysql-test/t/execution_constants.test	06/09/27 13:27:52
#
# Bug#21476: Lost Database Connection During Query
#
# When the amount of stack space we think we need to report an error is
# actually too small, then we can get SEGVs.  But, we don't want to reserve
# space that we could use to get real work done.  So, we want the reserved
# space small, and this test verifies that the reservation is not too small.

CREATE TABLE `t_bug21476` (
  `ID_BOARD` smallint(5) unsigned NOT NULL default '0',
  `ID_MEMBER` mediumint(8) unsigned NOT NULL default '0',
  `logTime` int(10) unsigned NOT NULL default '0',
  `ID_MSG` mediumint(8) unsigned NOT NULL default '0',
  PRIMARY KEY  (`ID_MEMBER`,`ID_BOARD`),
  KEY `logTime` (`logTime`)
) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_bulgarian_ci;

INSERT INTO `t_bug21476` VALUES (2,2,1154870939,0),(1,2,1154870957,0),(2,183,1154941362,0),(2,84,1154904301,0),(1,84,1154905867,0),(2,13,1154947484,10271),(3,84,1154880549,0),(1,6,1154892183,0),(2,25,1154947581,10271),(3,25,1154904760,0),(1,25,1154947373,10271),(1,179,1154899992,0),(2,179,1154899410,0),(5,25,1154901666,0),(2,329,1154902026,0),(3,329,1154902040,0),(1,329,1154902058,0),(1,13,1154930841,0),(3,85,1154904987,0),(1,183,1154929665,0),(3,13,1154931268,0),(1,85,1154936888,0),(1,169,1154937959,0),(2,169,1154941717,0),(3,183,1154939810,0),(3,169,1154941734,0);

delimiter //;
let $query_head=UPDATE t_bug21476 SET ID_MSG = IF(logTime BETWEEN 1 AND 1101770053, 2, //
let $query_tail =) WHERE logTime BETWEEN 1 AND 1104091539 AND ID_MSG = 0//

# Well more than enough recursions to find the end of our stack.
let $i = 100000//
disable_query_log//
disable_result_log//
while ($i)
{
  # If we SEGV because the min stack size is exceeded, this would return error 2013
  error 0,1436 //
  eval $query_head 0 $query_tail//

  if ($mysql_errno != 1436)
  {
    # end
    let $i = 1//
  }

  # Multiplying by three stack frames should be fine enough resolution to find a gap we don't cover.
  # Trading exactness for speed.
  let $query_head = $query_head IF(logTime <= 1104091$i, $i, //
  let $query_tail =) $query_tail//

  let $query_head = $query_head IF(logTime <= 1104091$i, $i, //
  let $query_tail =) $query_tail//

  let $query_head = $query_head IF(logTime <= 1104091$i, $i, //
  let $query_tail =) $query_tail//

  dec $i//
}
enable_result_log//
enable_query_log//

echo Assertion: mysql_errno 1436 == $mysql_errno//

delimiter ;//
DROP TABLE `t_bug21476`;

--echo End of 5.0 tests.


--- 1.5/BitKeeper/etc/collapsed	2006-09-27 13:27:58 -04:00
+++ 1.6/BitKeeper/etc/collapsed	2006-09-27 13:27:58 -04:00
@@ -3,3 +3,4 @@
 44edb86b1iE5knJ97MbliK_3lCiAXA
 44f33f3aj5KW5qweQeekY1LU0E9ZCg
 4513d8e4Af4dQWuk13sArwofRgFDQw
+4519a6c5BVUxEHTf5iJnjZkixMBs8g

--- 1.35/mysql-test/r/mysqltest.result	2006-09-27 13:27:58 -04:00
+++ 1.36/mysql-test/r/mysqltest.result	2006-09-27 13:27:58 -04:00
@@ -217,8 +217,11 @@ hej
 
 a long variable content
 a long variable content
-a long $where variable content
+a long a long variable content variable content
+a long \$where variable content
 
+banana = banana
+Not a banana: ba\$cat\$cat
 mysqltest: At line 1: Missing arguments to let
 mysqltest: At line 1: Missing variable name in let
 mysqltest: At line 1: Variable name in hi=hi does not start with '$'

--- 1.44/mysql-test/t/mysqltest.test	2006-09-27 13:27:58 -04:00
+++ 1.45/mysql-test/t/mysqltest.test	2006-09-27 13:27:58 -04:00
@@ -507,9 +507,21 @@ echo $where2;
 let $where3=a long $where variable content;
 echo $where3;
 
+let $where3=a long \\\$where variable content;
+echo $where3;
+
 let $novar1= $novar2;
 echo $novar1;
 
+let $cat=na;
+let $cat=ba$cat$cat;
+echo banana = $cat;
+
+# ba\$cat\$cat should have been sufficient.
+# ba\\\$cat\\\$cat -> ba\$cat\$cat -> ba$cat$cat -> banana
+# Magnus' upcoming patch will fix the missing second interpretation.
+let $cat=ba\\\$cat\\\$cat;
+echo Not a banana: $cat;
 
 
 # Test illegal uses of let

--- 1.241/client/mysqltest.c	2006-09-27 13:27:58 -04:00
+++ 1.242/client/mysqltest.c	2006-09-27 13:27:58 -04:00
@@ -1609,7 +1609,10 @@ int do_save_master_pos()
 int do_let(struct st_query *query)
 {
   char *p= query->first_argument;
-  char *var_name, *var_name_end, *var_val_start;
+  char *var_name, *var_name_end;
+  DYNAMIC_STRING let_rhs_expr;
+
+  init_dynamic_string(&let_rhs_expr, "", 16384, 65536);
 
   /* Find <var_name> */
   if (!*p)
@@ -1628,10 +1631,12 @@ int do_let(struct st_query *query)
   /* Find start of <var_val> */
   while (*p && my_isspace(charset_info,*p))
     p++;
-  var_val_start= p;
+
+  do_eval(&let_rhs_expr, p, FALSE);
+
   query->last_argument= query->end;
   /* Assign var_val to var_name */
-  return var_set(var_name, var_name_end, var_val_start, query->end);
+  return var_set(var_name, var_name_end, let_rhs_expr.str, let_rhs_expr.str+let_rhs_expr.length);
 }
 
 
Thread
bk commit into 5.0 tree (cmiller:1.2284) BUG#21476Chad MILLER27 Sep