Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/cgreen/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ set(cgreen_HDRS
cute_reporter.h
legacy.h
mocks.h
memory.h
string_comparison.h
reporter.h
runner.h
Expand Down
1 change: 1 addition & 0 deletions include/cgreen/cgreen.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
#include <cgreen/cute_reporter.h>
#include <cgreen/assertions.h>
#include <cgreen/constraint_syntax_helpers.h>
#include <cgreen/memory.h>
#include <cgreen/runner.h>
#include <cgreen/boxed_double.h>
1 change: 1 addition & 0 deletions include/cgreen/constraint_syntax_helpers.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#define will_return_double(value) create_return_double_value_constraint(value)
#define will_set_contents_of_parameter(parameter_name, value, size) create_set_parameter_value_constraint(#parameter_name, (intptr_t)value, (size_t)size)

void check_memory_leak(TestReporter *reporter);

#ifdef __cplusplus
extern "C" {
Expand Down
22 changes: 22 additions & 0 deletions include/cgreen/memory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef MEMORY_HEADER
#define MEMORY_HEADER

#ifndef __cplusplus
void* cgreen_malloc(size_t size, const char * filename, int line);
#define malloc(size) cgreen_malloc(size, __FILE__, __LINE__)

void* cgreen_calloc(size_t num_members, size_t size, const char * filename, int line);
#define calloc(num_members, size) cgreen_calloc(num_members, size, __FILE__, __LINE__)

void* cgreen_realloc(void* pointer, size_t size, const char * filename, int line);
#define realloc(pointer, size) cgreen_realloc(pointer, size, __FILE__, __LINE__)

void cgreen_free(void* pointer, const char * filename, int line);
#define free(pointer) cgreen_free(pointer, __FILE__, __LINE__)

#else
#undef check_memory_leak
#define check_memory_leak(reporter)
#endif

#endif
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ set(cgreen_SRCS
constraint_syntax_helpers.c
cute_reporter.c
cdash_reporter.c
memory.c
messaging.c
message_formatting.c
mocks.c
Expand Down
182 changes: 127 additions & 55 deletions src/memory.c
Original file line number Diff line number Diff line change
@@ -1,78 +1,150 @@
#include <stdlib.h>
#include <string.h>
#include "memory.h"
#include <include/cgreen/reporter.h>
#include <stdio.h>
#include "include/cgreen/memory.h"

#define MEMORY_INCREMENT 1024
typedef struct MemoryEntry_ {
void * memory_location;
size_t size;
const char* filename;
int line_number;
} MemoryEntry;

struct MemoryPool_ {
void** blocks;
long size;
long space;
};

static void enlarge(MemoryPool *pool);
static int move_to_front(MemoryPool *pool, void *pointer);
static void move_up_one(void **blocks, long amount);
static MemoryEntry ** allocation_memory = NULL;
static int number_of_memory_entries = 0;

MemoryPool *create_memory_pool() {
MemoryPool *pool = (MemoryPool *)malloc(sizeof(MemoryPool));
if (pool == NULL) {
return NULL;
}
pool->blocks = (void **)malloc(MEMORY_INCREMENT * sizeof(void *));
if (pool->blocks == NULL) {
free(pool);
return NULL;
}
pool->size = 0;
pool->space = MEMORY_INCREMENT;
return pool;

static int find_memory_position(void * pointer);
static void move_memory_back(int position_to_start_on);
static MemoryEntry * get_memory_entry(void * pointer);

#undef malloc
static void create_allocation_memory(void) {
allocation_memory = malloc(sizeof(MemoryEntry)*100);
}
#define malloc cgreen_malloc

void free_memory_pool(MemoryPool *pool) {
long i;
for (i = 0; i < pool->size; i++) {
free(pool->blocks[i]);
}
free(pool->blocks);
free(pool);
#undef malloc
void* cgreen_malloc(size_t size, const char * filename, int line) {
if(allocation_memory == NULL)
create_allocation_memory();

void * new_memory_pointer = malloc(size);
MemoryEntry * new_memory_entry = malloc(sizeof(MemoryEntry));
new_memory_entry->memory_location = new_memory_pointer;
new_memory_entry->size = size;
new_memory_entry->filename = filename;
new_memory_entry->line_number = line;
allocation_memory[number_of_memory_entries] = new_memory_entry;
number_of_memory_entries++;

return new_memory_pointer;
}
#define malloc cgreen_malloc

void *memory_pool_allocate(MemoryPool *pool, size_t bytes) {
enlarge(pool);
return pool->blocks[pool->size++] = malloc(bytes);
void* cgreen_calloc(size_t num_members, size_t size, const char * filename, int line) {
void * allocated_memory = cgreen_malloc(num_members * size, filename, line);
if (allocated_memory)
memset(allocated_memory, 0, num_members * size);
return allocated_memory;
}

void *memory_pool_reallocate(MemoryPool *pool, void *pointer, size_t bytes) {
if (! move_to_front(pool, pointer)) {
void* cgreen_realloc(void* pointer, size_t size, const char * filename, int line) {
if (pointer == NULL)
return cgreen_malloc(size, filename, line);

if (size == 0) {
cgreen_free(pointer, filename, line);
return NULL;
}
return pool->blocks[0] = realloc(pool->blocks[0], bytes);

MemoryEntry * memory_position = get_memory_entry(pointer);

void * new_pointer = cgreen_malloc(size, filename, line);

size_t actual_size = size;
if (size > memory_position->size)
actual_size = memory_position->size;

memcpy(new_pointer, pointer, actual_size);

cgreen_free(pointer, filename, line);

return new_pointer;
}

static void enlarge(MemoryPool *pool) {
if (pool->size == pool->space) {
pool->blocks = (void**)realloc(pool->blocks, (pool->space + MEMORY_INCREMENT) * sizeof(void *));
pool->space += MEMORY_INCREMENT;

#undef free
void cgreen_free(void * pointer, const char * filename, const int line) {
va_list null_arguments;
memset(&null_arguments, 0, sizeof(null_arguments));
if (pointer == NULL) {

TestReporter *reporter = get_test_reporter();
reporter->show_fail(reporter, filename, line, "Trying to free memory using a NULL pointer", null_arguments);
send_reporter_exception_notification(reporter);
return;
}

int memory_position = find_memory_position(pointer);

if (memory_position == -1) {
char message[100];
sprintf(message, "Trying to free memory [%p] that was not previously allocated", pointer);

TestReporter *reporter = get_test_reporter();
reporter->show_fail(reporter, filename, line, message, null_arguments);
send_reporter_exception_notification(reporter);
return;
}

free(allocation_memory[memory_position]);
move_memory_back(memory_position);
number_of_memory_entries--;
}
#define free cgreen_free

static int move_to_front(MemoryPool *pool, void *pointer) {
long i;
for (i = 1; i < pool->size; i++) {
if (pool->blocks[i] == pointer) {
move_up_one(pool->blocks, i);
pool->blocks[0] = pointer;
return 1;
void check_memory_leak(TestReporter *reporter) {
if (number_of_memory_entries > 0) {
for( int i = 0 ; i < number_of_memory_entries ; i++) {
MemoryEntry * memoryEntry = allocation_memory[i];
(reporter->assert_true)(
reporter,
memoryEntry->filename,
memoryEntry->line_number,
0,
"Memory allocated [%p] was not freed [%s:%d]",
memoryEntry->memory_location,
memoryEntry->filename,
memoryEntry->line_number
);
}
}
return 0;
}

/* static void move_up_one(void **blocks, long amount) { */
/* if (amount == 0) { */
/* return; */
/* } */
/* // FIXME: this doesn't compile and the semantics might be wrong */
/* //memmove(blocks[0], blocks[1], (size_t)(blocks[amount] - blocks[1])); */
/* } */
int find_memory_position(void * pointer) {
for( int i = 0 ; i < number_of_memory_entries ; i++) {
MemoryEntry * memoryEntry = allocation_memory[i];
if(memoryEntry && memoryEntry->memory_location == pointer)
return i;
}

return -1;
}

MemoryEntry * get_memory_entry(void * pointer) {
int position = find_memory_position(pointer);

if (position == -1)
return NULL;

return allocation_memory[position];
}

void move_memory_back(int position_to_start_on) {
for(int i = position_to_start_on ; i < number_of_memory_entries - 1 ; i++) {
allocation_memory[i] = allocation_memory[i+1];
}
}
12 changes: 0 additions & 12 deletions src/memory.h

This file was deleted.

1 change: 1 addition & 0 deletions src/message_formatting.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#endif

#include "constraint_internal.h"
#include <cgreen/memory.h>


// Handling of percent signs
Expand Down
5 changes: 5 additions & 0 deletions src/messaging.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <sched.h>
#endif

#include <cgreen/memory.h>

#define message_content_size(Type) (sizeof(Type) - sizeof(long))

Expand Down Expand Up @@ -61,6 +62,7 @@ int get_pipe_write_handle(void)

static void clean_up_messaging(void);

#undef realloc
int start_cgreen_messaging(int tag) {
CgreenMessageQueue *tmp;
int pipes[2];
Expand Down Expand Up @@ -95,6 +97,7 @@ int start_cgreen_messaging(int tag) {
queues[queue_count - 1].tag = tag;
return queue_count - 1;
}
#define realloc cgreen_realloc

void send_cgreen_message(int messaging, int result) {
CgreenMessage *message;
Expand Down Expand Up @@ -128,6 +131,7 @@ int receive_cgreen_message(int messaging) {
return result;
}

#undef free
static void clean_up_messaging(void) {
int i;
for (i = 0; i < queue_count; i++) {
Expand All @@ -140,5 +144,6 @@ static void clean_up_messaging(void) {
queues = NULL;
queue_count = 0;
}
#define free cgreen_free

/* vim: set ts=4 sw=4 et cindent: */
6 changes: 4 additions & 2 deletions src/posix_cgreen_pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
/* One way to do it the old way is: ioctl(fd, FIOBIO, &flags); */
#endif


#undef malloc
#undef free
int cgreen_pipe_open(int pipes[2])
{
int pipe_open_result;
Expand Down Expand Up @@ -70,5 +71,6 @@ ssize_t cgreen_pipe_write(int p, const void *buf, size_t count)
}
return pipe_write_result;
}

#define malloc cgreen_malloc
#define free cgreen_free
/* vim: set ts=4 sw=4 et cindent: */
1 change: 1 addition & 0 deletions src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <cgreen/memory.h>


char *string_dup(const char *string) {
Expand Down
12 changes: 12 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,11 @@ set(xml_output_library_SRCS xml_output_tests.c)
add_library(${xml_output_library} SHARED ${xml_output_library_SRCS})
target_link_libraries(${xml_output_library} ${CGREEN_LIBRARY})

set(memory_leak_library memory_leak_tests)
set(memory_leak_library_SRCS memory_leak_tests.c)
add_library(${memory_leak_library} SHARED ${memory_leak_library_SRCS})
target_link_libraries(${memory_leak_library} ${CGREEN_LIBRARY})

set(TEST_TARGET_LIBRARIES ${CGREEN_LIBRARY})

macro_add_test(
Expand Down Expand Up @@ -224,5 +229,12 @@ macro_add_test(NAME xml_output
${xml_output_library}.expected
)

macro_add_test(NAME memory_leaks
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/../tools/cgreen_runner_output_diff
memory_leak_tests # Name
${CMAKE_CURRENT_SOURCE_DIR} # Where sources are
${memory_leak_library}.expected
)

# add verification that all public api is available as it should
add_subdirectory(api)
Loading