Bug #8058 | Crashes and out of memory in SQL parsing of stored procs | ||
---|---|---|---|
Submitted: | 20 Jan 2005 23:03 | Modified: | 21 Feb 2005 16:50 |
Reporter: | Heikki Tuuri | Email Updates: | |
Status: | Can't repeat | Impact on me: | |
Category: | MySQL Server | Severity: | S1 (Critical) |
Version: | 5.0.3 built today | OS: | Linux (Linux/x86) |
Assigned to: | Bugs System | CPU Architecture: | Any |
[20 Jan 2005 23:03]
Heikki Tuuri
[20 Jan 2005 23:16]
Heikki Tuuri
Hi! I forgot to mention that I used the MySQL system tables from /mysql-5.0/mysql-test/master-data/mysql/ in my test. I also noticed that if some of the system tables were missing, mysqld crashed in query_cache_invalidate() (spelling?) when trying to print an error message. That bug is already in the bugs database, from fall 2004. Regards, Heikki
[21 Jan 2005 0:24]
Heikki Tuuri
Hi! The query_cache_abort() crash is bug #7186. Heikki
[21 Jan 2005 2:06]
MySQL Verification Team
Hi Heikki, I wasn't able to repeat this on Slackaware with latest BK source. I tested several times.
[21 Jan 2005 10:09]
Heikki Tuuri
Hi! hundin has been very reliable, and I recompiled mysqld several times. After a fresh mysqld restart inside gdb, I was able to get a crashes with a MyISAM table, too. This could also be a bug in the mysql client / mysqld server communication. An uninitialized variable or memory corruption. I have also pasted below stack traces from three MyISAM-only crashes. In the last one I tried to print interesting variables from the stack. Regards, Heikki delimiter ? drop database test? create database test? use test create table t (a int not null primary key, b char(10), c int, index(c)) type = myisam; ? CREATE PROCEDURE insert100000() BEGIN DECLARE i INT; SET AUTOCOMMIT=0; SET i = 1; WHILE i < 100000 DO INSERT INTO t VALUES(i, '0123456789', i); SET i = i + 1; END WHILE; COMMIT; END; ? CREATE PROCEDURE tpca10000() BEGIN DECLARE i INT; SET AUTOCOMMIT=0; SET i = 0; WHILE i < 10000 DO UPDATE t SET b = 'a23456789' WHERE a = i + 500; UPDATE t SET b = 'a23456789' WHERE a = i + 10500; UPDATE t SET b = 'a23456789' WHERE a = i + 20500; INSERT INTO t VALUES (100000 + i, '0123456789', 5); COMMIT; SET i = i + 1; END WHILE; END; ? call insert100000();? call tpca10000();? heikki@hundin:~/mysql-5.0/sql> gdb mysqld GNU gdb 6.0 Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"... (gdb) run Starting program: /home/heikki/mysql-5.0/sql/mysqld [New Thread 16384 (LWP 8605)] [New Thread 32769 (LWP 8607)] [New Thread 16386 (LWP 8608)] [New Thread 32771 (LWP 8609)] [New Thread 49156 (LWP 8610)] [New Thread 65541 (LWP 8611)] InnoDB: Starting to apply log records to the database... [New Thread 81926 (LWP 8612)] [New Thread 98311 (LWP 8613)] [New Thread 114696 (LWP 8614)] [New Thread 131081 (LWP 8615)] 050121 11:04:47 InnoDB: Started; log sequence number 0 299913166 [New Thread 147466 (LWP 8616)] /home/heikki/mysql-5.0/sql/mysqld: ready for connections. Version: '5.0.3-alpha-debug-log' socket: '/home/heikki/bugsocket' port: 3307 Source distribution [New Thread 163851 (LWP 8630)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 163851 (LWP 8630)] 0x401941bc in memcpy () from /lib/i686/libc.so.6 (gdb) bt #0 0x401941bc in memcpy () from /lib/i686/libc.so.6 #1 0x083afe36 in strmake_root (root=0x8bf7ea0, str=0x8bf7ea0 "è @\bØ\231Y\bÜ\231Y\bø @\b", len=147140608) at my_alloc.c:339 #2 0x081a4c78 in yyparse(void*) (yythd=0x8bf7ea0) at sql_yacc.yy:1892 #3 0x0819f374 in mysql_parse(THD*, char*, unsigned) (thd=0x8bf7ea0, inBuf=0x8c20d20 "CREATE PROCEDURE tpca10000()\nBEGIN\n DECLARE i INT;\n SET AUTOCOMMIT=0;\n SET i = 0;\n WHILE i < 10000 DO\n UPDATE t SET b = 'a23456789' WHERE a = i + 500;\n UPDATE t SET b = 'a23456789' WHERE a = i + 105"..., length=146767584) at sql_parse.cc:4715 #4 0x08196b04 in dispatch_command(enum_server_command, THD*, char*, unsigned) (command=COM_QUERY, thd=0x8bf7ea0, packet=0x8c18cc1 "CREATE PROCEDURE tpca10000()\nBEGIN\n DECLARE i INT;\n SET AUTOCOMMIT=0;\n SET i = 0;\n WHILE i < 10000 DO\n UPDATE t SET b = 'a23456789' WHERE a = i + 500;\n UPDATE t SET b = 'a23456789' WHERE a = i + 105"..., packet_length=354) at sql_parse.cc:1533 #5 0x081963f4 in do_command(THD*) (thd=0x8bf7ea0) at sql_parse.cc:1341 #6 0x0819578e in handle_one_connection (arg=0x8bf7ea0) at sql_parse.cc:1060 #7 0x40062f60 in pthread_start_thread () from /lib/i686/libpthread.so.0 #8 0x400630fe in pthread_start_thread_event () from /lib/i686/libpthread.so.0 #9 0x401f5327 in clone () from /lib/i686/libc.so.6 ------------------------------------------------ I ran concurrently: heikki@hundin:~/test> perl run-all-tests --create-options=type=myisam Benchmark DBD suite: 2.14 Date of test: 2005-01-21 11:18:21 Running tests on: Linux 2.4.21-99-smp i686 Arguments: --create-options=type=myisam Comments: Limits from: Server version: MySQL 5.0.3 alpha debug log alter-table: heikki@hundin:~/mysql-5.0/sql> gdb mysqld GNU gdb 6.0 Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i686-pc-linux-gnu"... (gdb) run Starting program: /home/heikki/mysql-5.0/sql/mysqld [New Thread 16384 (LWP 8780)] [New Thread 32769 (LWP 8782)] [New Thread 16386 (LWP 8783)] [New Thread 32771 (LWP 8784)] [New Thread 49156 (LWP 8785)] [New Thread 65541 (LWP 8786)] InnoDB: Starting to apply log records to the database... [New Thread 81926 (LWP 8787)] [New Thread 98311 (LWP 8788)] [New Thread 114696 (LWP 8789)] [New Thread 131081 (LWP 8790)] 050121 11:16:46 InnoDB: Started; log sequence number 0 299918168 [New Thread 147466 (LWP 8791)] /home/heikki/mysql-5.0/sql/mysqld: ready for connections. Version: '5.0.3-alpha-debug-log' socket: '/home/heikki/bugsocket' port: 3307 Source distribution [New Thread 163851 (LWP 8805)] [New Thread 180236 (LWP 8809)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 163851 (LWP 8805)] 0x401941bc in memcpy () from /lib/i686/libc.so.6 (gdb) bt #0 0x401941bc in memcpy () from /lib/i686/libc.so.6 #1 0x083afe36 in strmake_root (root=0x8c035e8, str=0x8c035e8 "è @\bØ\231Y\b\bèÁ\bø @\b", len=1197699071) at my_alloc.c:339 #2 0x081a4c78 in yyparse(void*) (yythd=0x8c035e8) at sql_yacc.yy:1892 #3 0x082a4d88 in db_find_routine (thd=0x8c035e8, type=2, name=0x47604de8, sphp=0x449b75d4) at sp.cc:299 #4 0x082a6757 in sp_find_procedure(THD*, sp_name*) (thd=0x8c035e8, name=0x47604de8) at sp.cc:732 #5 0x0819d2e4 in mysql_execute_command(THD*) (thd=0x8c035e8) at sql_parse.cc:3807 #6 0x0819f421 in mysql_parse(THD*, char*, unsigned) (thd=0x8c035e8, inBuf=0x47604d90 "call tpca10000()", length=146814504) at sql_parse.cc:4738 #7 0x08196b04 in dispatch_command(enum_server_command, THD*, char*, unsigned) (command=COM_QUERY, thd=0x8c035e8, packet=0x8c51031 "call tpca10000();", packet_length=18) at sql_parse.cc:1533 #8 0x081963f4 in do_command(THD*) (thd=0x8c035e8) at sql_parse.cc:1341 #9 0x0819578e in handle_one_connection (arg=0x8c035e8) at sql_parse.cc:1060 #10 0x40062f60 in pthread_start_thread () from /lib/i686/libpthread.so.0 #11 0x400630fe in pthread_start_thread_event () from /lib/i686/libpthread.so.0 #12 0x401f5327 in clone () from /lib/i686/libc.so.6 (gdb) ------------------------------------------------------ Ran this concurrently: heikki@hundin:~/test> perl run-all-tests --create-options=type=myisam Benchmark DBD suite: 2.14 Date of test: 2005-01-21 11:23:54 Running tests on: Linux 2.4.21-99-smp i686 Arguments: --create-options=type=myisam Comments: Limits from: Server version: MySQL 5.0.3 alpha debug log alter-table: Starting program: /home/heikki/mysql-5.0/sql/mysqld [New Thread 16384 (LWP 8851)] [New Thread 32769 (LWP 8856)] [New Thread 16386 (LWP 8857)] [New Thread 32771 (LWP 8858)] [New Thread 49156 (LWP 8859)] [New Thread 65541 (LWP 8860)] 050121 11:23:28 InnoDB: Database was not shut down normally! InnoDB: Starting crash recovery. InnoDB: Reading tablespace information from the .ibd files... InnoDB: Restoring possible half-written data pages from the doublewrite InnoDB: buffer... 050121 11:23:28 InnoDB: Starting log scan based on checkpoint at InnoDB: log sequence number 0 299918208. InnoDB: Doing recovery: scanned up to log sequence number 0 299918208 InnoDB: Starting to apply log records to the database... InnoDB: Last MySQL binlog file position 0 95, file name ./binlog.000021 [New Thread 81926 (LWP 8861)] [New Thread 98311 (LWP 8862)] [New Thread 114696 (LWP 8863)] [New Thread 131081 (LWP 8864)] 050121 11:23:28 InnoDB: Started; log sequence number 0 299918208 [New Thread 147466 (LWP 8865)] /home/heikki/mysql-5.0/sql/mysqld: ready for connections. Version: '5.0.3-alpha-debug-log' socket: '/home/heikki/bugsocket' port: 3307 Source distribution [New Thread 163851 (LWP 8866)] [New Thread 180236 (LWP 8900)] Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 163851 (LWP 8866)] 0x401941bc in memcpy () from /lib/i686/libc.so.6 (gdb) bt #0 0x401941bc in memcpy () from /lib/i686/libc.so.6 #1 0x083afe36 in strmake_root (root=0x8c18cc0, str=0x8c18cc0 "è @\b\bñÃ\bÜ\231Y\bø @\b", len=1197608959) at my_alloc.c:339 #2 0x081a4c78 in yyparse(void*) (yythd=0x8c18cc0) at sql_yacc.yy:1892 #3 0x082a4d88 in db_find_routine (thd=0x8c18cc0, type=2, name=0x8c24d80, sphp=0x449b75d4) at sp.cc:299 #4 0x082a6757 in sp_find_procedure(THD*, sp_name*) (thd=0x8c18cc0, name=0x8c24d80) at sp.cc:732 #5 0x0819d2e4 in mysql_execute_command(THD*) (thd=0x8c18cc0) at sql_parse.cc:3807 #6 0x0819f421 in mysql_parse(THD*, char*, unsigned) (thd=0x8c18cc0, inBuf=0x8c24d28 "call tpca10000()", length=146902272) at sql_parse.cc:4738 #7 0x08196b04 in dispatch_command(enum_server_command, THD*, char*, unsigned) (command=COM_QUERY, thd=0x8c18cc0, packet=0x8bffec1 "call tpca10000();", packet_length=18) at sql_parse.cc:1533 #8 0x081963f4 in do_command(THD*) (thd=0x8c18cc0) at sql_parse.cc:1341 #9 0x0819578e in handle_one_connection (arg=0x8c18cc0) at sql_parse.cc:1060 #10 0x40062f60 in pthread_start_thread () from /lib/i686/libpthread.so.0 #11 0x400630fe in pthread_start_thread_event () from /lib/i686/libpthread.so.0 #12 0x401f5327 in clone () from /lib/i686/libc.so.6 (gdb) frame 3 #3 0x082a4d88 in db_find_routine (thd=0x8c18cc0, type=2, name=0x8c24d80, sphp=0x449b75d4) at sp.cc:299 299 if (yyparse(thd) || thd->is_fatal_error || thd->lex->sphead == NULL) (gdb) print name $1 = (class sp_name *) 0x8c24d80 (gdb) print *name $2 = {<Sql_alloc> = {<No data fields>}, m_db = {str = 0x8c24d78 "test2", length = 5}, m_name = {str = 0x8c24d68 "tpca10000", length = 9}, m_qname = {str = 0x8c24d98 "test2.tpca10000", length = 15}} (gdb) list 294 295 lex_start(thd, (uchar*)defstr.c_ptr(), defstr.length()); 296 thd->lex->value_list= vals; 297 } 298 299 if (yyparse(thd) || thd->is_fatal_error || thd->lex->sphead == NULL) 300 { 301 LEX *newlex= thd->lex; 302 sp_head *sp= newlex->sphead; 303 (gdb) frame 2 #2 0x081a4c78 in yyparse(void*) (yythd=0x8c18cc0) at sql_yacc.yy:1892 1892 i->m_query.str= strmake_root(YYTHD->mem_root, (gdb) list 1887 The end is either lex->tok_end or tok->ptr. */ 1888 if (lex->ptr - lex->tok_end > 1) 1889 i->m_query.length= lex->ptr - sp->m_tmp_query; 1890 else 1891 i->m_query.length= lex->tok_end - sp->m_tmp_query; 1892 i->m_query.str= strmake_root(YYTHD->mem_root, 1893 (char *)sp->m_tmp_query, 1894 i->m_query.length); 1895 i->set_lex(lex); 1896 sp->add_instr(i); (gdb) print *sp $3 = {<Item_arena> = {_vptr.Item_arena = 0x84591d0, free_list = 0x0, main_mem_root = {free = 0x476006b8, used = 0x47700020, pre_alloc = 0x476006b8, min_malloc = 32, block_size = 8136, block_num = 5, first_block_usage = 0, error_handler = 0}, mem_root = 0x476006d0, backup_arena = 165, state = INITIALIZED}, m_type = 2, m_returns = -1515870811, m_returns_cs = 0x0, m_has_return = 0 '\0', m_simple_case = 0 '\0', m_multi_results = 0 '\0', m_in_handler = 0 '\0', m_tmp_query = 0x47600622 "COMMIT;\n SET i = i + 1;\n END WHILE;\nEND", m_old_cmq = 65536, m_chistics = 0x8c19364, m_sql_mode = 2779096485, m_qname = {str = 0x0, length = 0}, m_db = {str = 0x0, length = 0}, m_name = { str = 0x0, length = 0}, m_params = {str = 0x0, length = 0}, m_retstr = { str = 0x0, length = 0}, m_body = {str = 0x0, length = 0}, m_defstr = { str = 0x0, length = 0}, m_definer_user = {str = 0xa5a5a5a5 "", length = 2779096485}, m_definer_host = {str = 0xa5a5a5a5 "", length = 2779096485}, m_created = -6510615555426900571, m_modified = -6510615555426900571, m_param_begin = 0x47600505 ")\nBEGIN\n DECLARE i INT;\n SET AUTOCOMMIT=0;\n SE T i = 0;\n WHILE i < 10000 DO\n UPDATE t SET b = 'a23456789' WHERE a = i + 500; \n UPDATE t SET b = 'a23456789' WHERE a = i + 10500;\n UPDATE t SET b = 'a23". .., m_param_end = 0x47600505 ")\nBEGIN\n DECLARE i INT;\n SET AUTOCOMMIT=0;\n SET i = 0;\n WHILE i < 10000 DO\n UPDATE t SET b = 'a23456789' WHERE a = i + 500;\n UPDATE t SET b = 'a23456789' WHERE a = i + 10500;\n UPDATE t SET b = 'a23"... , m_returns_begin = 0x0, m_returns_end = 0x0, m_body_begin = 0x47600507 "BEGIN\n DECLARE i INT;\n SET AUTOCOMMIT=0;\n SET i = 0;\n WHILE i < 10000 DO\n UPDATE t SET b = 'a23456789' WHERE a = i + 500;\n UPDATE t SET b = 'a23456789' WHERE a = i + 10500;\n UPDATE t SET b = 'a2345"... , m_thd_root = 0x8c18cd4, m_thd = 0x8c18cc0, m_thd_db = 0x8c5dea0 "test2", m_pcont = 0x476007d0, m_lex = {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x47602000, last = 0x47602000, elements = 1}, <No data fields>}, m_instr = { buffer = 0x47602848 "\220\t`G0\n`Gà\v`G\030\021`Gh\026`GÀ\e`G¨\037`G", '¥' < repeats 36 times>, "h4z\025e", elements = 7, max_element = 16, alloc_increment = 8, size_of_element = 4}, m_backpatch = {<base_list> = {<Sql_alloc> = {<No data fields>}, first = 0x47600c10, last = 0x47600c10, elements = 1}, <No data fields>}} (gdb)
[21 Jan 2005 18:23]
Per-Erik Martin
I couldn't get it to crash, but when running with valgrind there is a complaint in the parser.
[26 Jan 2005 20:41]
Jorge del Conde
I was able to reproduce this using 5.0.3 in XP
[21 Feb 2005 16:50]
Per-Erik Martin
I still can't get it to crash, and there's no longer any complaint from valgrind. I tried a valgrind-max build with and without valgrind and gdb, and a -max build (optimized).