Fail cleanly on allocation failures
Previously code in the SWIG tool didn't handle allocation failures well. Most places didn't check for NULL return from malloc()/realloc()/calloc() at all, typically resulting in undefined behaviour, and some places used assert() to check for a NULL return (which is a misuse of assert() and such checks disappear if built with NDEBUG defined leaving us back with undefined behaviour). All C allocations are now done via wrapper functions (Malloc(), Realloc() and Calloc()) which emit and error and exit with non-zero status on failure, so a non-NULL return can be relied upon. Fixes #1901.
This commit is contained in:
parent
9eb75a0c07
commit
e38847f7e1
14 changed files with 83 additions and 65 deletions
|
|
@ -14,6 +14,9 @@
|
|||
|
||||
#include "dohint.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef DOH_POOL_SIZE
|
||||
#define DOH_POOL_SIZE 4194304
|
||||
#endif
|
||||
|
|
@ -48,10 +51,7 @@ static int pools_initialized = 0;
|
|||
static void CreatePool() {
|
||||
Pool *p = 0;
|
||||
p = (Pool *) DohMalloc(sizeof(Pool));
|
||||
assert(p);
|
||||
p->ptr = (DohBase *) DohMalloc(sizeof(DohBase) * PoolSize);
|
||||
assert(p->ptr);
|
||||
memset(p->ptr, 0, sizeof(DohBase) * PoolSize);
|
||||
p->ptr = (DohBase *) DohCalloc(PoolSize, sizeof(DohBase));
|
||||
p->len = PoolSize;
|
||||
p->blen = PoolSize * sizeof(DohBase);
|
||||
p->current = 0;
|
||||
|
|
@ -234,3 +234,40 @@ void DohMemoryDebug(void) {
|
|||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void allocation_failed(size_t n, size_t size) {
|
||||
/* Report and exit as directly as possible to try to avoid further issues due
|
||||
* to lack of memory. */
|
||||
if (n == 1) {
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L
|
||||
fprintf(stderr, "Failed to allocate %zu bytes\n", size);
|
||||
#else
|
||||
fprintf(stderr, "Failed to allocate %lu bytes\n", (unsigned long)size);
|
||||
#endif
|
||||
} else {
|
||||
#if defined __STDC_VERSION__ && __STDC_VERSION__-0 >= 19901L
|
||||
fprintf(stderr, "Failed to allocate %zu*%zu bytes\n", n, size);
|
||||
#else
|
||||
fprintf(stderr, "Failed to allocate %lu*%lu bytes\n", (unsigned long)n, (unsigned long)size);
|
||||
#endif
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
void *DohMalloc(size_t size) {
|
||||
void *p = malloc(size);
|
||||
if (!p) allocation_failed(1, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
void *DohRealloc(void *ptr, size_t size) {
|
||||
void *p = realloc(ptr, size);
|
||||
if (!p) allocation_failed(1, size);
|
||||
return p;
|
||||
}
|
||||
|
||||
void *DohCalloc(size_t n, size_t size) {
|
||||
void *p = calloc(n, size);
|
||||
if (!p) allocation_failed(n, size);
|
||||
return p;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue