memcheck.c 2.4 KB
Newer Older
1 2 3 4 5 6 7 8
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include "system.h"

void memcheck()
{
9 10
//#define MEMCHECK
#ifdef MEMCHECK
11 12 13 14 15 16 17 18
    uint32_t patterns[] = {
        0x0,
        0xFFFFFFFF,
        0xAAAAAAAA,
        0x55555555,
        0xAA55AA55,
        0x55AA55AA,
    };
19
    unsigned primes[] = { 3, 7, 31, 127 };
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
    size_t space = 512*1024;
    void *p = malloc(space);
    int i;

    printf("[MEMCHECK] Detecting memory available");
    while(p) {
        free(p);
        printf(".");
        fflush(stdout);
        space += 1024*1024;
        p = malloc(space);
    }
    space -= 1024*1024;
    printf("\n[MEMCHECK] Memory available: %dK\n", space/1024);

    p = malloc(space);
    if (!p) {
        puts("[MEMCHECK] Unexpected heap error. Aborting...");
        fflush(stdout);
        exit(1);
    }

42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
    // Check potential address space overlaps
    printf("[MEMCHECK] Checking for potential address space overlap. Window: ");
    for (i=0; i<sizeof(primes)/sizeof(primes[0]); i++) {
        uint8_t *pc = p;
        unsigned prime = primes[i];
        unsigned bytes = space;
        unsigned idx = 0;
        printf("%s%d", i?", ":"", prime);
        fflush(stdout);
        while (bytes--) {
            *pc++ = (idx % prime);
            idx++;
        }
        pc = p;
        bytes = space;
        idx = 0;
        while (bytes--) {
            if (*pc != (idx % prime)) {
                printf("[MEMCHECK] Address space wrapped around at 0x%x!\n", (unsigned)pc);
                fflush(stdout);
                exit(1);
            }
            pc++;
            idx++;
        }
    }
    puts("");

70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
    for(i=0; i<sizeof(patterns)/sizeof(patterns[0]); i++) {
        printf("[MEMCHECK] Checking memory with pattern: 0x%x...\n", (unsigned) patterns[i]);
        uint32_t *pw = p;
        unsigned words = space/4;
        // Writing the pattern
        while(words--) {
            *pw++ = patterns[i];
        }
        pw = p;
        words = space/4;
        // Verifying the pattern
        while(words--) {
            if (*pw != patterns[i]) {
                printf(
                    "[MEMCHECK] Failed with pattern 0x%x at offset 0x%x\n",
                    (unsigned)patterns[i], (unsigned)pw);
                fflush(stdout);
                exit(1);
            }
            pw++;
        }
    }
    free(p);
93 94 95 96
#else
    puts("[MEMCHECK] Memory checks disabled in release mode.");
    fflush(stdout);
#endif
97
}