Bug #49514 Server crash in recursive call when OOM
Submitted: 7 Dec 2009 16:16 Modified: 15 Jan 2013 16:31
Reporter: Marc ALFF Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Errors Severity:S2 (Serious)
Version:5.1, all OS:Any
Assigned to: CPU Architecture:Any

[7 Dec 2009 16:16] Marc ALFF
Description:
When the server is out of memory, an error is raised to indicate that.
However, handling the error itself causes more memory allocations that fail,
causing the error handling code to loop with recursion,
leading to a stack overflow.

(...)
#1397 0x0000000000f1dd9e in my_message (error=5, 
    str=0x4264d090 "Out of memory at line 201, 'my_alloc.c'", 
    MyFlags=123591592) at my_error.c:165
#1398 0x0000000000f4610e in _mymalloc (size=1980, 
    filename=0x12b5d80 "my_alloc.c", lineno=201, MyFlags=1040)
    at safemalloc.c:164
#1399 0x0000000000f4068b in alloc_root (mem_root=0x42650000, length=376)
    at my_alloc.c:201
#1400 0x00000000005e5bab in Sql_alloc::operator new (size=376, 
    mem_root=0x42650000) at ../sql_list.h:45
#1401 0x0000000000907c12 in Warning_info::push_warning (this=0x42650000, 
    thd=0x75ddba8, sql_errno=5, sqlstate=0x11a6591 "HY000", 
    level=MYSQL_ERROR::WARN_LEVEL_ERROR, 
    msg=0x4264d5e0 "Out of memory at line 201, 'my_alloc.c'")
    at sql_error.cc:557
#1402 0x000000000076ad1e in THD::raise_condition_no_handler (this=0x75ddba8, 
    sql_errno=5, sqlstate=0x11a6591 "HY000", 
    level=MYSQL_ERROR::WARN_LEVEL_ERROR, 
    msg=0x4264d5e0 "Out of memory at line 201, 'my_alloc.c'")
    at sql_class.cc:838
#1403 0x000000000076b360 in THD::raise_condition (this=0x75ddba8, sql_errno=5, 
    sqlstate=0x11a6591 "HY000", level=MYSQL_ERROR::WARN_LEVEL_ERROR, 
    msg=0x4264d5e0 "Out of memory at line 201, 'my_alloc.c'")
    at sql_class.cc:819
#1404 0x0000000000798609 in my_message_sql (error=5, 
    str=0x4264d5e0 "Out of memory at line 201, 'my_alloc.c'", MyFlags=100)
    at mysqld.cc:3318
#1405 0x0000000000f1dd9e in my_message (error=5, 
    str=0x4264d5e0 "Out of memory at line 201, 'my_alloc.c'", 
    MyFlags=123591592) at my_error.c:165
#1406 0x0000000000f4610e in _mymalloc (size=1980, 
    filename=0x12b5d80 "my_alloc.c", lineno=201, MyFlags=1040)
    at safemalloc.c:164
#1407 0x0000000000f4068b in alloc_root (mem_root=0x42650000, length=376)
    at my_alloc.c:201
#1408 0x00000000005e5bab in Sql_alloc::operator new (size=376, 
    mem_root=0x42650000) at ../sql_list.h:45
#1409 0x0000000000907c12 in Warning_info::push_warning (this=0x42650000, 
    thd=0x75ddba8, sql_errno=5, sqlstate=0x11a6591 "HY000", 
    level=MYSQL_ERROR::WARN_LEVEL_ERROR, 
    msg=0x4264db30 "Out of memory at line 1048, 'filesort.cc'")
    at sql_error.cc:557
#1410 0x000000000076ad1e in THD::raise_condition_no_handler (this=0x75ddba8, 
    sql_errno=5, sqlstate=0x11a6591 "HY000", 
    level=MYSQL_ERROR::WARN_LEVEL_ERROR, 
    msg=0x4264db30 "Out of memory at line 1048, 'filesort.cc'")
    at sql_class.cc:838
#1411 0x000000000076b360 in THD::raise_condition (this=0x75ddba8, sql_errno=5, 
    sqlstate=0x11a6591 "HY000", level=MYSQL_ERROR::WARN_LEVEL_ERROR, 
    msg=0x4264db30 "Out of memory at line 1048, 'filesort.cc'")
    at sql_class.cc:819
#1412 0x0000000000798609 in my_message_sql (error=5, 
    str=0x4264db30 "Out of memory at line 1048, 'filesort.cc'", MyFlags=100)
    at mysqld.cc:3318
#1413 0x0000000000f1dd9e in my_message (error=5, 
    str=0x4264db30 "Out of memory at line 1048, 'filesort.cc'", 
    MyFlags=123591592) at my_error.c:165
#1414 0x0000000000f4610e in _mymalloc (size=2256, 
    filename=0x1231aa0 "filesort.cc", lineno=1048, MyFlags=16)
    at safemalloc.c:164
#1415 0x00000000009efee0 in save_index (param=0x4264e1a0, sort_keys=0x795e1d8, 
    count=282, table_sort=0x4264e220) at filesort.cc:1047
#1416 0x00000000009f097f in filesort (thd=0x75ddba8, table=0x75cdb70, 
    sortorder=0x79432b0, s_length=1, select=0x7942fb0, 
    max_rows=18446744073709551615, sort_positions=false, 
    examined_rows=0x4264e3a8) at filesort.cc:254
#1417 0x00000000008b42a7 in create_sort_index (thd=0x75ddba8, join=0x7956430, 
    order=0x7746ba8, filesort_limit=18446744073709551615, 
    select_limit=18446744073709551615, is_order_by=false)
    at sql_select.cc:19332
#1418 0x00000000008d8f05 in JOIN::exec (this=0x7956430) at sql_select.cc:2892
#1419 0x00000000008d0580 in mysql_select (thd=0x75ddba8, 
    rref_pointer_array=0x7746028, tables=0x7718930, wild_num=1, 
    fields=@0x7745f48, conds=0x7746918, og_num=1, order=0x7746ba8, group=0x0, 
    having=0x0, proc_param=0x0, select_options=2684620288, result=0x79426b8, 
    unit=0x7745790, select_lex=0x7745e40) at sql_select.cc:3140
#1420 0x00000000008d9831 in handle_select (thd=0x75ddba8, lex=0x77456f0, 
    result=0x79426b8, setup_tables_done_option=0) at sql_select.cc:308
#1421 0x00000000007b81c7 in execute_sqlcom_select (thd=0x75ddba8, 
    all_tables=0x7718930) at sql_parse.cc:4946
#1422 0x00000000007b9cae in mysql_execute_command (thd=0x75ddba8)
    at sql_parse.cc:2164
#1423 0x0000000000b11009 in sp_instr_stmt::exec_core (this=0x7746bf0, 
    thd=0x75ddba8, nextp=0x42650168) at sp_head.cc:2925
#1424 0x0000000000b1206e in sp_lex_keeper::reset_lex_and_exec_core (
    this=0x7746c30, thd=0x75ddba8, nextp=0x42650168, open_tables=false, 
    instr=0x7746bf0) at sp_head.cc:2748
#1425 0x0000000000b12be8 in sp_instr_stmt::execute (this=0x7746bf0, 
    thd=0x75ddba8, nextp=0x42650168) at sp_head.cc:2863
#1426 0x0000000000b1633a in sp_head::execute (this=0x77170e0, thd=0x75ddba8)
    at sp_head.cc:1245
#1427 0x0000000000b17abf in sp_head::execute_procedure (this=0x77170e0, 
    thd=0x75ddba8, args=0x75e00e8) at sp_head.cc:1985
#1428 0x00000000007c4910 in mysql_execute_command (thd=0x75ddba8)
    at sql_parse.cc:4404
#1429 0x00000000007c7843 in mysql_parse (thd=0x75ddba8, 
    inBuf=0x7720ec0 "call mtr.check_testcase()", length=25, 
    found_semicolon=0x42651ef0) at sql_parse.cc:5977
#1430 0x00000000007c9b38 in dispatch_command (command=COM_QUERY, 
    thd=0x75ddba8, packet=0x770d219 "call mtr.check_testcase()", 
    packet_length=25) at sql_parse.cc:1084
#1431 0x00000000007cbea1 in do_command (thd=0x75ddba8) at sql_parse.cc:766
#1432 0x00000000007ac5ea in do_handle_one_connection (thd_arg=0x75ddba8)
    at sql_connect.cc:1174
#1433 0x00000000007ac7a9 in handle_one_connection (arg=0x75ddba8)
    at sql_connect.cc:1114
#1434 0x0000003a23e062f7 in start_thread () from /lib64/libpthread.so.0
#1435 0x0000003a232d1b6d in clone () from /lib64/libc.so.6

How to repeat:
Hard to reproduce.

Currently affects bug46080.test in mysql-6.0-codebase-perfschema,
for GCOV builds, but the exact conditions to trigger that changes depending
on the code / environment / platform.

Suggested fix:
N/A
[13 Dec 2009 10:04] Sveta Smirnova
Thank you for the report.

Verified as described.

To see the problem apply following patch, then run test for bug #46080.

$bzr diff
=== modified file 'mysys/safemalloc.c'
--- mysys/safemalloc.c  2009-05-15 07:53:50 +0000
+++ mysys/safemalloc.c  2009-12-13 09:32:42 +0000
@@ -67,6 +67,7 @@
 #include <m_string.h>
 #include "my_static.h"
 #include "mysys_err.h"
+#include "bug49514.h"
 
 ulonglong sf_malloc_mem_limit= ~(ulonglong)0;
 
@@ -133,6 +134,7 @@
     irem= 0;
   else
   {
+if (!bug49514)
     /* Allocate the physical memory */
     irem= (struct st_irem *) malloc (ALIGN_SIZE(sizeof(struct st_irem)) +
                                     sf_malloc_prehunc +

=== modified file 'sql/item_sum.cc'
--- sql/item_sum.cc     2009-12-08 09:26:11 +0000
+++ sql/item_sum.cc     2009-12-13 09:46:52 +0000
@@ -27,6 +27,7 @@
 
 #include "mysql_priv.h"
 #include "sql_select.h"
+#include "bug49514.h"
 
 /**
   Prepare an aggregate function item for checking context conditions.
@@ -3152,7 +3153,7 @@
     if (count == unique_filter->elements_in_tree())
       row_eligible= FALSE;
   }
-
+bug49514 = TRUE;
   TREE_ELEMENT *el= 0;                          // Only for safety
   if (row_eligible && tree)
   {
@@ -3170,6 +3171,7 @@
   if (row_eligible && !warning_for_row &&
       (!tree || (el->count == 1 && distinct && !arg_count_order)))
     dump_leaf_key(table->record[0] + table->s->null_bytes, 1, this);
+bug49514=FALSE;
 
   return 0;
 }

=== modified file 'sql/mysqld.cc'
--- sql/mysqld.cc       2009-11-20 12:09:50 +0000
+++ sql/mysqld.cc       2009-12-13 09:57:29 +0000
@@ -27,6 +27,7 @@
 #include "mysys_err.h"
 #include "events.h"
 #include "debug_sync.h"
+//#include "bug49514.h"
 
 #include "../storage/myisam/ha_myisam.h"
 
@@ -4686,6 +4687,8 @@
 
 int main(int argc, char **argv)
 {
+
+  bug49514 = FALSE;
   /*
     When several instances are running on the same machine, we
     need to have an  unique  named  hEventShudown  through the
[15 Jan 2013 16:31] Paul DuBois
Noted in 5.5.31, 5.6.11, 5.7.1 changelogs.

An out-of-memory condition could occur while handling an
out-of-memory error, leading to recursion in error handling.