Changeset View
Changeset View
Standalone View
Standalone View
test/scudo/sizes.cpp
Show All 15 Lines | |||||
#include <assert.h> | #include <assert.h> | ||||
#include <malloc.h> | #include <malloc.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include <limits> | #include <limits> | ||||
#include <new> | #include <new> | ||||
#include <sanitizer/allocator_interface.h> | |||||
int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||
assert(argc == 2); | assert(argc == 2); | ||||
const char *action = argv[1]; | |||||
fprintf(stderr, "%s:\n", action); | |||||
#if __LP64__ || defined(_WIN64) | #if __LP64__ || defined(_WIN64) | ||||
static const size_t kMaxAllowedMallocSize = 1ULL << 40; | static const size_t kMaxAllowedMallocSize = 1ULL << 40; | ||||
static const size_t kChunkHeaderSize = 16; | static const size_t kChunkHeaderSize = 16; | ||||
#else | #else | ||||
static const size_t kMaxAllowedMallocSize = 2UL << 30; | static const size_t kMaxAllowedMallocSize = 2UL << 30; | ||||
static const size_t kChunkHeaderSize = 8; | static const size_t kChunkHeaderSize = 8; | ||||
#endif | #endif | ||||
if (!strcmp(action, "malloc")) { | if (!strcmp(argv[1], "malloc")) { | ||||
void *p = malloc(kMaxAllowedMallocSize); | void *p = malloc(kMaxAllowedMallocSize); | ||||
assert(!p); | assert(!p); | ||||
p = malloc(kMaxAllowedMallocSize - kChunkHeaderSize); | p = malloc(kMaxAllowedMallocSize - kChunkHeaderSize); | ||||
assert(!p); | assert(!p); | ||||
} else if (!strcmp(action, "calloc")) { | } else if (!strcmp(argv[1], "calloc")) { | ||||
// Trigger an overflow in calloc. | // Trigger an overflow in calloc. | ||||
size_t size = std::numeric_limits<size_t>::max(); | size_t size = std::numeric_limits<size_t>::max(); | ||||
void *p = calloc((size / 0x1000) + 1, 0x1000); | void *p = calloc((size / 0x1000) + 1, 0x1000); | ||||
assert(!p); | assert(!p); | ||||
} else if (!strcmp(action, "new")) { | } else if (!strcmp(argv[1], "new")) { | ||||
void *p = operator new(kMaxAllowedMallocSize); | void *p = operator new(kMaxAllowedMallocSize); | ||||
assert(!p); | assert(!p); | ||||
} else if (!strcmp(action, "new-nothrow")) { | } else if (!strcmp(argv[1], "new-nothrow")) { | ||||
void *p = operator new(kMaxAllowedMallocSize, std::nothrow); | void *p = operator new(kMaxAllowedMallocSize, std::nothrow); | ||||
assert(!p); | assert(!p); | ||||
} else if (!strcmp(action, "usable")) { | } else if (!strcmp(argv[1], "usable")) { | ||||
// Playing with the actual usable size of a chunk. | // Playing with the actual usable size of a chunk. | ||||
void *p = malloc(1007); | void *p = malloc(1007); | ||||
assert(p); | assert(p); | ||||
size_t size = malloc_usable_size(p); | size_t size = __sanitizer_get_allocated_size(p); | ||||
assert(size >= 1007); | assert(size >= 1007); | ||||
memset(p, 'A', size); | memset(p, 'A', size); | ||||
p = realloc(p, 2014); | p = realloc(p, 2014); | ||||
assert(p); | assert(p); | ||||
size = malloc_usable_size(p); | size = __sanitizer_get_allocated_size(p); | ||||
assert(size >= 2014); | assert(size >= 2014); | ||||
memset(p, 'B', size); | memset(p, 'B', size); | ||||
free(p); | free(p); | ||||
} else { | } else { | ||||
assert(0); | assert(0); | ||||
} | } | ||||
return 0; | return 0; | ||||
} | } | ||||
// CHECK: allocator is terminating the process | // CHECK: allocator is terminating the process |