malloc/t/fuzzy.c

108 lines
3.6 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
struct item {
void *ptr;
size_t size;
size_t hash;
};
static void hash_compute(struct item *item) {
unsigned char c;
size_t hash = 0xdeadbeef;
for (size_t i = 0; i < item->size; i++) {
c = rand();
((unsigned char *)item->ptr)[i] = c;
hash += (hash << 13) ^ c;
hash ^= (hash << 26) - (c * ((hash >> 56) + 1));
}
item->hash = hash;
}
static int hash_check(struct item *item) {
unsigned char c;
size_t hash = 0xdeadbeef;
if (item->ptr == NULL)
return 1;
for (size_t i = 0; i < item->size; i++) {
c = ((unsigned char *)item->ptr)[i];
hash += (hash << 13) ^ c;
hash ^= (hash << 26) - (c * ((hash >> 56) + 1));
}
return (item->hash == hash);
}
int main(int argc, const char *const argv[]) {
if (argc < 4) {
puts("Usage: ... num_passes num_items size_min size_max");
return 1;
}
size_t num_passes = atoi(argv[1]),
num_items = atoi(argv[2]),
size_min = atoi(argv[3]),
size_max = atoi(argv[4]);
struct item items[num_items];
srand(argc + num_items + size_min + size_max);
srand(rand() ^ time(NULL));
bzero(items, sizeof(struct item) * num_items);
for (size_t pass = 0; pass < num_passes; pass++) {
for (size_t i = 0; i < num_items; i++) {
if (pass % 3 == 0) {
if (rand() & 1 && items[i].ptr == NULL) {
items[i].size = rand() % (size_max - size_min) + size_min;
items[i].ptr = malloc(items[i].size);
if (items[i].ptr) {
hash_compute(&items[i]);
printf("pass %-2lu item %-4lu malloc(%lu) => %p..%p\n",
pass, i, items[i].size, items[i].ptr, items[i].ptr + items[i].size);
} else {
printf("\033[0;31mpass %-2lu item %-4lu returned NULL\033[0m\n", pass, i);
}
}
} else if (pass % 3 == 1) {
if (rand() & 1 && items[i].ptr != NULL) {
void *old_ptr = items[i].ptr;
items[i].size = rand() % (size_max - size_min) + size_min;
items[i].ptr = realloc(items[i].ptr, items[i].size);
if (items[i].ptr) {
hash_compute(&items[i]);
printf("pass %-2lu item %-4lu realloc(%p, %lu) => %p\n",
pass, i, old_ptr, items[i].size, items[i].ptr);
} else {
printf("\033[0;31mpass %-2lu item %-4lu realloc failed\033[0m\n", pass, i);
}
}
} else {
if (rand() & 1 && items[i].ptr != NULL) {
printf("pass %-2lu item %-4lu free(%p)\n",
pass, i, items[i].ptr);
free(items[i].ptr);
items[i].ptr = NULL;
} else if (pass == num_passes - 1 && items[i].ptr != NULL) {
printf("pass %-2lu item %-4lu free(%p)\n",
pass, i, items[i].ptr);
free(items[i].ptr);
items[i].ptr = NULL;
}
}
for (size_t j = 0; j < num_items; j++) {
if (!hash_check(&items[i])) {
printf("\033[0;31mpass %-2lu item %-4lu hash_check failed\033[0m\n", pass, i);
items[i].ptr = NULL;
}
}
}
/* show_alloc_mem(); */
}
return (0);
}