1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-25 16:13:17 +00:00

Return NULL if there is an OOM error during initialization, rather than

allowing the error to be fatal.

Move a label in order to make sure to properly handle errors in malloc(0).

Reported by:	Alastair D'Silva, Saneto Takanori
This commit is contained in:
Jason Evans 2006-01-19 02:11:05 +00:00
parent 239cc3b6ce
commit 2addd81287
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=154546

View File

@ -870,7 +870,7 @@ static void *iralloc(arena_t *arena, void *ptr, size_t size);
static void istats(size_t *allocated, size_t *total);
#endif
static void malloc_print_stats(void);
static void malloc_init_hard(void);
static bool malloc_init_hard(void);
/*
* End function prototypes.
@ -4238,7 +4238,7 @@ malloc_print_stats(void)
* since otherwise choose_arena() has no way to know whether it's safe
* to call _pthread_self().
*/
static __inline void
static __inline bool
malloc_init(void)
{
@ -4249,10 +4249,12 @@ malloc_init(void)
assert(__isthreaded == 0 || malloc_initialized);
if (malloc_initialized == false)
malloc_init_hard();
return (malloc_init_hard());
return (false);
}
static void
static bool
malloc_init_hard(void)
{
unsigned i, j;
@ -4515,8 +4517,8 @@ malloc_init_hard(void)
/* Allocate and initialize arenas. */
arenas = (arena_t **)base_alloc(sizeof(arena_t *) * narenas);
/* OOM here is fatal. */
assert(arenas != NULL);
if (arenas == NULL)
return (true);
/*
* Zero the array. In practice, this should always be pre-zeroed,
* since it was just mmap()ed, but let's be sure.
@ -4528,12 +4530,13 @@ malloc_init_hard(void)
* arena_choose_hard().
*/
arenas_extend(0);
/* OOM here is fatal. */
assert(arenas[0] != NULL);
if (arenas[0] == NULL)
return (true);
malloc_mutex_init(&arenas_mtx);
malloc_initialized = true;
return (false);
}
/*
@ -4550,7 +4553,10 @@ malloc(size_t size)
void *ret;
arena_t *arena;
malloc_init();
if (malloc_init()) {
ret = NULL;
goto RETURN;
}
if (size == 0) {
if (opt_sysv == false)
@ -4566,6 +4572,7 @@ malloc(size_t size)
else
ret = NULL;
RETURN:
if (ret == NULL) {
if (opt_xmalloc) {
malloc_printf("%s: (malloc) Error in malloc(%zu):"
@ -4576,7 +4583,6 @@ malloc(size_t size)
} else if (opt_zero)
memset(ret, 0, size);
RETURN:
UTRACE(0, size, ret);
return (ret);
}
@ -4588,26 +4594,30 @@ posix_memalign(void **memptr, size_t alignment, size_t size)
arena_t *arena;
void *result;
malloc_init();
/* Make sure that alignment is a large enough power of 2. */
if (((alignment - 1) & alignment) != 0 || alignment < sizeof(void *)) {
if (opt_xmalloc) {
malloc_printf("%s: (malloc) Error in"
" posix_memalign(%zu, %zu): invalid alignment\n",
_getprogname(), alignment, size);
abort();
if (malloc_init())
result = NULL;
else {
/* Make sure that alignment is a large enough power of 2. */
if (((alignment - 1) & alignment) != 0
|| alignment < sizeof(void *)) {
if (opt_xmalloc) {
malloc_printf("%s: (malloc) Error in"
" posix_memalign(%zu, %zu):"
" invalid alignment\n",
_getprogname(), alignment, size);
abort();
}
result = NULL;
ret = EINVAL;
goto RETURN;
}
result = NULL;
ret = EINVAL;
goto RETURN;
}
arena = choose_arena();
if (arena != NULL)
result = ipalloc(arena, alignment, size);
else
result = NULL;
arena = choose_arena();
if (arena != NULL)
result = ipalloc(arena, alignment, size);
else
result = NULL;
}
if (result == NULL) {
if (opt_xmalloc) {
@ -4635,7 +4645,10 @@ calloc(size_t num, size_t size)
void *ret;
arena_t *arena;
malloc_init();
if (malloc_init()) {
ret = NULL;
goto RETURN;
}
if (num * size == 0) {
if (opt_sysv == false)
@ -4712,13 +4725,15 @@ realloc(void *ptr, size_t size)
}
}
} else {
malloc_init();
arena = choose_arena();
if (arena != NULL)
ret = imalloc(arena, size);
else
if (malloc_init())
ret = NULL;
else {
arena = choose_arena();
if (arena != NULL)
ret = imalloc(arena, size);
else
ret = NULL;
}
if (ret == NULL) {
if (opt_xmalloc) {