diff options
author | Nisha Gopalakrishnan <nisha.gopalakrishnan@oracle.com> | 2013-01-15 15:30:26 +0530 |
---|---|---|
committer | Nisha Gopalakrishnan <nisha.gopalakrishnan@oracle.com> | 2013-01-15 15:30:26 +0530 |
commit | 62e8f2567778e201164ba9e0195f13dfede56b42 (patch) | |
tree | c177ff5163e51c6d1c8953eeb892c7cc47ca220a /mysys | |
parent | a44084413cf48b37a6306e3e6ecf624b8696b330 (diff) | |
download | mariadb-git-62e8f2567778e201164ba9e0195f13dfede56b42.tar.gz |
Bug#11757464:SERVER CRASH IN RECURSIVE CALL WHEN OOM
Analysis:
---------
When the server is out of memory, an error is raised
to indicate the same. Handling the error requires
more memory to be allocated which fails, hence the
error handling loops in a recursion and causes the
server to crash.
Fix:
---
a) Prevents pushing the 'out of memory' error condition
to the diagnostic area as it requires memory allocation.
GET DIAGNOSTICS, SHOW WARNINGS and SHOW ERRORS statements
will not show information about this error. However the
'out of memory' error is returned to the client.
b) It sets the ME_FATALERROR flag when 'out of memory' errors
are reported (for places where the flag is not already set).
This flag prevents activation of SP error handlers which also
require memory allocation and therefore are likely to fail.
Diffstat (limited to 'mysys')
-rw-r--r-- | mysys/mf_keycache.c | 3 | ||||
-rw-r--r-- | mysys/my_lockmem.c | 2 | ||||
-rw-r--r-- | mysys/my_malloc.c | 12 | ||||
-rw-r--r-- | mysys/my_once.c | 2 |
4 files changed, 13 insertions, 6 deletions
diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 7dfbf22d4b7..5829ab819f7 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -444,7 +444,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, if (blocks < 8) { my_errno= ENOMEM; - my_error(EE_OUTOFMEMORY, MYF(0), blocks * keycache->key_cache_block_size); + my_error(EE_OUTOFMEMORY, MYF(ME_FATALERROR), + blocks * keycache->key_cache_block_size); goto err; } blocks= blocks / 4*3; diff --git a/mysys/my_lockmem.c b/mysys/my_lockmem.c index 8f06192d9f8..2e036936c70 100644 --- a/mysys/my_lockmem.c +++ b/mysys/my_lockmem.c @@ -43,7 +43,7 @@ uchar *my_malloc_lock(uint size,myf MyFlags) if (!(ptr=memalign(pagesize,size))) { if (MyFlags & (MY_FAE+MY_WME)) - my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),size); + my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_FATALERROR), size); DBUG_RETURN(0); } success = mlock((uchar*) ptr,size); diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index fc2dc98c3c5..93eb547888f 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -41,6 +41,11 @@ void *my_malloc(size_t size, myf my_flags) free(point); point= NULL; }); + DBUG_EXECUTE_IF("simulate_persistent_out_of_memory", + { + free(point); + point= NULL; + }); if (point == NULL) { @@ -48,7 +53,8 @@ void *my_malloc(size_t size, myf my_flags) if (my_flags & MY_FAE) error_handler_hook=fatal_error_handler_hook; if (my_flags & (MY_FAE+MY_WME)) - my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH),size); + my_error(EE_OUTOFMEMORY, MYF(ME_BELL + ME_WAITTANG + + ME_NOREFRESH + ME_FATALERROR),size); DBUG_EXECUTE_IF("simulate_out_of_memory", DBUG_SET("-d,simulate_out_of_memory");); if (my_flags & MY_FAE) @@ -90,7 +96,7 @@ void *my_realloc(void *oldpoint, size_t size, myf my_flags) DBUG_RETURN(oldpoint); my_errno=errno; if (my_flags & MY_FAE+MY_WME) - my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),size); + my_error(EE_OUTOFMEMORY, MYF(ME_BELL + ME_WAITTANG + ME_FATALERROR),size); } else { @@ -106,7 +112,7 @@ void *my_realloc(void *oldpoint, size_t size, myf my_flags) DBUG_RETURN(oldpoint); my_errno=errno; if (my_flags & (MY_FAE+MY_WME)) - my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG), size); + my_error(EE_OUTOFMEMORY, MYF(ME_BELL + ME_WAITTANG + ME_FATALERROR), size); } #endif DBUG_PRINT("exit",("ptr: %p", point)); diff --git a/mysys/my_once.c b/mysys/my_once.c index 7df9b0a1981..b9232db9b2e 100644 --- a/mysys/my_once.c +++ b/mysys/my_once.c @@ -59,7 +59,7 @@ void* my_once_alloc(size_t Size, myf MyFlags) { my_errno=errno; if (MyFlags & (MY_FAE+MY_WME)) - my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),get_size); + my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_FATALERROR), get_size); return((uchar*) 0); } DBUG_PRINT("test",("my_once_malloc %lu byte malloced", (ulong) get_size)); |