How to force OS X malloc to automatically interrupt on crash?

Matasano's blog calls "Checking the return value malloc()" a "Anti-Idiom Programming". Instead, it malloc()should automatically call abort()for you if it fails. The argument is that since you usually want to interrupt the program if it malloc()doesn’t work, this should be the default behavior instead of what you need to type with difficulty - or maybe forget to enter! - Every time.

Without delving into the merits of an idea, what is the easiest way to customize this? I was looking for something that would automatically detect failures in memory allocation by other library functions such as asprintf(). A portable solution would be great, but Id would also be pleased with something Mac specific.


To summarize the best answers below:

Mac OS Solution

Set the environment variable MallocErrorAbort=1before running your program. Automatically works for all memory allocation functions.

Mac / linux runtime solution

Use the shim dynamic library to load a custom shell malloc()at run time with LD_PRELOADor DYLD_INSERT_LIBRARIES. Most likely, you'll want to wrap calloc(), realloc(), & c. also.

Mac / linux compiled solution

malloc() free() dyld(RTLD_NEXT, "malloc") . , , , calloc(), realloc(), & c. .

#include <dlfcn.h>
#include <stdio.h>
#include <stdlib.h>

void *(*system_malloc)(size_t) = NULL;

void* malloc(size_t bytes) {
    if (system_malloc == NULL) {
        system_malloc = dlsym(RTLD_NEXT, "malloc");
    }
    void* ret = system_malloc(bytes);
    if (ret == NULL) {
        perror("malloc failed, aborting");
        abort();
    }
    return ret;
}

int main() {
    void* m = malloc(10000000000000000l);
    if (m == NULL) {
        perror("malloc failed, program still running");
    }
    return 0;
}

Linux

__malloc_hook __realloc_hook, glibc manual.

Mac

malloc_default_zone() , , zone->malloc:

#include <malloc/malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>

static void* (*system_malloc)(struct _malloc_zone_t *zone, size_t size);
static void* my_malloc(struct _malloc_zone_t *zone, size_t size) {
    void* ret = system_malloc(zone, size);
    if (ret == NULL) {
        perror("malloc failed, aborting");
        abort();
    }
    return ret;
}

int main() {
    malloc_zone_t *zone = malloc_default_zone();
    if (zone->version != 8) {
        fprintf(stderr, "Unknown malloc zone version %d\n", zone->version);
        abort();
    }
    system_malloc = zone->malloc;
    if (mprotect(zone, getpagesize(), PROT_READ | PROT_WRITE) != 0) {
        perror("munprotect failed");
        abort();
    }
    zone->malloc = my_malloc;
    if (mprotect(zone, getpagesize(), PROT_READ) != 0) {
        perror("mprotect failed");
        abort();
    }

    void* m = malloc(10000000000000000l);
    if (m == NULL) {
        perror("malloc failed, program still running");
    }
    return 0;
}

, , calloc(), realloc() , malloc_zone_t /usr/include/malloc/malloc.h.

+5
2

malloc() my_malloc(), . , . malloc(), , , , .

, , , , . , ?

, asprintf, libc , ( valgrind ), malloc. , C , .

http://www.gnu.org/savannah-checkouts/gnu/libc/manual/html_node/Hooks-for-Malloc.html

+4

man malloc Mac . , MallocErrorAbort.

.

  • MallocLogFile <f>
    / <f> , .

  • MallocGuardEdges
    , .

  • MallocDoNotProtectPrelude
    , , ​​ MallocGuardEdges.

  • MallocDoNotProtectPostlude
    , , ​​ MallocGuardEdges.

  • MallocStackLogging
    , , , .

  • MallocStackLoggingNoCompact
    , , malloc_history.

  • MallocStackLoggingDirectory
    , , (/tmp).

  • MallocScribble
    , , 0xaa. , , , . , , , 0x55 . - , .

  • MallocCheckHeapStart <s>
    , <s> <n>, MallocCheckHeapEach. MallocCheckHeapStart , MallocCheckHeapEach , 1000.

  • MallocCheckHeapEach <n>
    , <n>. MallocCheckHeapEach , MallocCheckHeapStart.

  • MallocCheckHeapSleep <t>
    ( ), MallocCheckHeapStart . - 100 . . ( ) , .

  • MallocCheckHeapAbort <b>
    MallocCheckHeapStart, , (3), , .

  • MallocErrorAbort
    , abort (3), malloc (3) (3), , (3) .

  • MallocCorruptionAbort
    MallocErrorAbort, , , . MallocCorruptionAbort 64- .

  • MallocHelp
    , , , . .

MallocCorruptionAbort MallocErrorAbort.


- - emalloc(), erealloc(), ecalloc(), efree(), estrdup() .. - (efree() is ) . , . , ; , .

, . , , , , . ( ) , , . , , , " ". . ; , . .

+2

All Articles