From a95807706bb70b58ad986388343d868ccf34b2c5 Mon Sep 17 00:00:00 2001 From: hellolintong Date: Mon, 25 Jan 2016 01:10:54 +0800 Subject: [PATCH] update memory allocate check --- src/cmockery.c | 29 +++++++++++++++++++++++++++++ src/example/allocate_module.c | 15 +++++++++++++-- src/example/allocate_module_test.c | 17 +++++++++++++++++ 3 files changed, 59 insertions(+), 2 deletions(-) diff --git a/src/cmockery.c b/src/cmockery.c index df78ea2..992a00f 100755 --- a/src/cmockery.c +++ b/src/cmockery.c @@ -94,6 +94,7 @@ typedef struct ListNode { // Debug information for malloc(). typedef struct MallocBlockInfo { void* block; // Address of the block returned by malloc(). + void* ptr; // Address returned to caller size_t allocated_size; // Total size of the allocated block. size_t size; // Request block size. SourceLocation location; // Where the block was allocated. @@ -1361,6 +1362,7 @@ void* _test_malloc(const size_t size, const char* file, const int line) { block_info->allocated_size = allocate_size; block_info->size = size; block_info->block = block; + block_info->ptr = ptr; block_info->node.value = block_info; list_add(block_list, &block_info->node); return ptr; @@ -1377,6 +1379,22 @@ void* _test_calloc(const size_t number_of_elements, const size_t size, return ptr; } +//Chech if the address is really allocated +int check_allocated_exist(void* const ptr){ + const ListNode * const head = get_allocated_blocks_list(); + const ListNode *node = head->next; + int rc = 0; + while(node != head){ + const MallocBlockInfo * const block_info = (const MallocBlockInfo*)node->value; + assert_true(block_info); + if(block_info->ptr == ptr){ + rc = 1; + break; + } + node = node->next; + } + return rc; +} // Use the real free in this function. #undef free @@ -1385,6 +1403,17 @@ void _test_free(void* const ptr, const char* file, const int line) { char *block = (char*)ptr; MallocBlockInfo *block_info; _assert_true((int)ptr, "ptr", file, line); + + //is it a allocated block(maybe free twice) + if(!check_allocated_exist((void * const)ptr)){ + print_error( + "the address of 0x%08x in " + SOURCE_LOCATION_FORMAT " is not a allocated block\n", + (size_t)ptr, file, line + ); + _fail(file, line); + } + block_info = (MallocBlockInfo*)(block - (MALLOC_GUARD_SIZE + sizeof(*block_info))); // Check the guard blocks. diff --git a/src/example/allocate_module.c b/src/example/allocate_module.c index 634932b..1c2f4d9 100644 --- a/src/example/allocate_module.c +++ b/src/example/allocate_module.c @@ -21,7 +21,7 @@ #endif #include -#if UNIT_TESTING +//#if UNIT_TESTING extern void* _test_malloc(const size_t size, const char* file, const int line); extern void* _test_calloc(const size_t number_of_elements, const size_t size, const char* file, const int line); @@ -30,13 +30,24 @@ extern void _test_free(void* const ptr, const char* file, const int line); #define malloc(size) _test_malloc(size, __FILE__, __LINE__) #define calloc(num, size) _test_calloc(num, size, __FILE__, __LINE__) #define free(ptr) _test_free(ptr, __FILE__, __LINE__) -#endif // UNIT_TESTING +//#endif // UNIT_TESTING void leak_memory() { int * const temporary = (int*)malloc(sizeof(int)); *temporary = 0; } +void free_bad_memory() { + int counter = 0; + free(&counter); +} + +void free_twice_memory() { + int* temporary = (int*)malloc(sizeof(int)); + free(temporary); + free(temporary); +} + void buffer_overflow() { char * const memory = (char*)malloc(sizeof(int)); memory[sizeof(int)] = '!'; diff --git a/src/example/allocate_module_test.c b/src/example/allocate_module_test.c index 3e9c022..85ef71c 100644 --- a/src/example/allocate_module_test.c +++ b/src/example/allocate_module_test.c @@ -21,12 +21,27 @@ extern void leak_memory(); extern void buffer_overflow(); extern void buffer_underflow(); +extern void free_twice_memory(); +extern void free_bad_memory(); + // Test case that fails as leak_memory() leaks a dynamically allocated block. void leak_memory_test(void **state) { leak_memory(); } +// Test case that fails as free_twice_memory() free twice. +void free_twice_memory_test(void **state) { + free_twice_memory(); +} + +// Test case that fails as free_bad_memory() free bad memory. +void free_bad_memory_test(void **state) { + free_bad_memory(); +} + + + // Test case that fails as buffer_overflow() corrupts an allocated block. void buffer_overflow_test(void **state) { buffer_overflow(); @@ -42,6 +57,8 @@ int main(int argc, char* argv[]) { unit_test(leak_memory_test), unit_test(buffer_overflow_test), unit_test(buffer_underflow_test), + unit_test(free_twice_memory), + unit_test(free_bad_memory) }; return run_tests(tests); }