Skip to content

Commit eae3b4f

Browse files
Alexey KopytovAlexey Kopytov
authored andcommitted
Manual merge from mysql-5.1-bugteam to mysql-trunk-merge.
conflicts: conflict mysys/safemalloc.c conflict sql/mysqld.cc conflict sql/sp.cc conflict sql/sql_lex.cc conflict sql/sql_lex.h conflict sql/sql_parse.cc conflict sql/sql_prepare.cc
2 parents 6d38a62 + b497e2c commit eae3b4f

18 files changed

Lines changed: 179 additions & 47 deletions

mysql-test/r/error_simulation.result

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,14 @@ a
3939
2
4040
DROP TABLE t1;
4141
#
42+
# Bug#42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string
43+
#
44+
CREATE TABLE t1(a BLOB);
45+
SET SESSION debug="+d,bug42064_simulate_oom";
46+
INSERT INTO t1 VALUES("");
47+
Got one of the listed errors
48+
SET SESSION debug=DEFAULT;
49+
DROP TABLE t1;
50+
#
4251
# End of 5.1 tests
4352
#

mysql-test/t/error_simulation.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ SELECT * FROM t1;
4646
DROP TABLE t1;
4747

4848

49+
--echo #
50+
--echo # Bug#42064: low memory crash when importing hex strings, in Item_hex_string::Item_hex_string
51+
--echo #
52+
53+
CREATE TABLE t1(a BLOB);
54+
55+
SET SESSION debug="+d,bug42064_simulate_oom";
56+
# May fail with either ER_OUT_OF_RESOURCES or EE_OUTOFMEMORY
57+
--error ER_OUT_OF_RESOURCES, 5
58+
INSERT INTO t1 VALUES("");
59+
SET SESSION debug=DEFAULT;
60+
61+
DROP TABLE t1;
62+
4963
--echo #
5064
--echo # End of 5.1 tests
5165
--echo #

mysys/my_alloc.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,14 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
154154

155155
DBUG_ASSERT(alloc_root_inited(mem_root));
156156

157+
DBUG_EXECUTE_IF("simulate_out_of_memory",
158+
{
159+
if (mem_root->error_handler)
160+
(*mem_root->error_handler)();
161+
DBUG_SET("-d,simulate_out_of_memory");
162+
DBUG_RETURN((void*) 0); /* purecov: inspected */
163+
});
164+
157165
length+=ALIGN_SIZE(sizeof(USED_MEM));
158166
if (!(next = (USED_MEM*) my_malloc(length,MYF(MY_WME | ME_FATALERROR))))
159167
{
@@ -176,6 +184,14 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length)
176184
DBUG_PRINT("enter",("root: 0x%lx", (long) mem_root));
177185
DBUG_ASSERT(alloc_root_inited(mem_root));
178186

187+
DBUG_EXECUTE_IF("simulate_out_of_memory",
188+
{
189+
/* Avoid reusing an already allocated block */
190+
if (mem_root->error_handler)
191+
(*mem_root->error_handler)();
192+
DBUG_SET("-d,simulate_out_of_memory");
193+
DBUG_RETURN((void*) 0); /* purecov: inspected */
194+
});
179195
length= ALIGN_SIZE(length);
180196
if ((*(prev= &mem_root->free)) != NULL)
181197
{

mysys/my_malloc.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,23 @@ void *my_malloc(size_t size, myf my_flags)
3131

3232
if (!size)
3333
size=1; /* Safety */
34-
if ((point = (char*)malloc(size)) == NULL)
34+
35+
point= (char *) malloc(size);
36+
DBUG_EXECUTE_IF("simulate_out_of_memory",
37+
{
38+
free(point);
39+
point= NULL;
40+
});
41+
42+
if (point == NULL)
3543
{
3644
my_errno=errno;
3745
if (my_flags & MY_FAE)
3846
error_handler_hook=fatal_error_handler_hook;
3947
if (my_flags & (MY_FAE+MY_WME))
4048
my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH),size);
49+
DBUG_EXECUTE_IF("simulate_out_of_memory",
50+
DBUG_SET("-d,simulate_out_of_memory"););
4151
if (my_flags & MY_FAE)
4252
exit(1);
4353
}

mysys/safemalloc.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,11 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags)
139139
size + /* size requested */
140140
4 + /* overrun mark */
141141
sf_malloc_endhunc);
142+
DBUG_EXECUTE_IF("simulate_out_of_memory",
143+
{
144+
free(irem);
145+
irem= NULL;
146+
});
142147
}
143148
/* Check if there isn't anymore memory avaiable */
144149
if (!irem)
@@ -159,6 +164,8 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags)
159164
}
160165
DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'",
161166
(long)sf_malloc_max_memory,lineno, filename));
167+
DBUG_EXECUTE_IF("simulate_out_of_memory",
168+
DBUG_SET("-d,simulate_out_of_memory"););
162169
if (MyFlags & MY_FAE)
163170
exit(1);
164171
DBUG_RETURN ((void*) 0);

sql/event_data_objects.cc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1447,7 +1447,10 @@ Event_job_data::execute(THD *thd, bool drop)
14471447
thd->set_query(sp_sql.c_ptr_safe(), sp_sql.length());
14481448

14491449
{
1450-
Parser_state parser_state(thd, thd->query(), thd->query_length());
1450+
Parser_state parser_state;
1451+
if (parser_state.init(thd, thd->query(), thd->query_length()))
1452+
goto end;
1453+
14511454
lex_start(thd);
14521455

14531456
if (parse_sql(thd, & parser_state, creation_ctx))

sql/log_event.cc

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3254,9 +3254,12 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli,
32543254
thd->table_map_for_update= (table_map)table_map_for_update;
32553255

32563256
/* Execute the query (note that we bypass dispatch_command()) */
3257-
Parser_state parser_state(thd, thd->query(), thd->query_length());
3258-
mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
3259-
log_slow_statement(thd);
3257+
Parser_state parser_state;
3258+
if (!parser_state.init(thd, thd->query(), thd->query_length()))
3259+
{
3260+
mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
3261+
log_slow_statement(thd);
3262+
}
32603263

32613264
/*
32623265
Resetting the enable_slow_log thd variable.

sql/mysqld.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3113,6 +3113,10 @@ void my_message_sql(uint error, const char *str, myf MyFlags)
31133113
MYSQL_ERROR::WARN_LEVEL_ERROR,
31143114
str);
31153115
}
3116+
3117+
/* When simulating OOM, skip writing to error log to avoid mtr errors */
3118+
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_VOID_RETURN;);
3119+
31163120
if (!thd || MyFlags & ME_NOREFRESH)
31173121
sql_print_error("%s: %s",my_progname,str); /* purecov: inspected */
31183122
DBUG_VOID_RETURN;

sql/sp.cc

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -720,11 +720,18 @@ static sp_head *sp_compile(THD *thd, String *defstr, ulong sql_mode,
720720
ha_rows old_select_limit= thd->variables.select_limit;
721721
sp_rcontext *old_spcont= thd->spcont;
722722
Silence_deprecated_warning warning_handler;
723+
Parser_state parser_state;
723724

724725
thd->variables.sql_mode= sql_mode;
725726
thd->variables.select_limit= HA_POS_ERROR;
726727

727-
Parser_state parser_state(thd, defstr->c_ptr(), defstr->length());
728+
if (parser_state.init(thd, defstr->c_ptr(), defstr->length()))
729+
{
730+
thd->variables.sql_mode= old_sql_mode;
731+
thd->variables.select_limit= old_select_limit;
732+
return NULL;
733+
}
734+
728735
lex_start(thd);
729736
thd->push_internal_handler(&warning_handler);
730737
thd->spcont= 0;

sql/sql_class.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,9 @@ THD::raise_condition_no_handler(uint sql_errno,
878878
if (no_warnings_for_error && (level == MYSQL_ERROR::WARN_LEVEL_ERROR))
879879
DBUG_RETURN(NULL);
880880

881+
/* When simulating OOM, skip writing to error log to avoid mtr errors */
882+
DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_RETURN(NULL););
883+
881884
cond= warning_info->push_warning(this, sql_errno, sqlstate, level, msg);
882885
DBUG_RETURN(cond);
883886
}

0 commit comments

Comments
 (0)