diff options
-rw-r--r-- | CMakeLists.txt | 14 | ||||
-rw-r--r-- | config.h.cmake | 2 | ||||
-rw-r--r-- | src/libical/CMakeLists.txt | 6 | ||||
-rw-r--r-- | src/libical/icalmemory.c | 15 | ||||
-rw-r--r-- | src/test/regression.c | 5 | ||||
-rw-r--r-- | src/test/test-malloc.c | 5 |
6 files changed, 40 insertions, 7 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 82b14260..3f726faa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,6 +78,14 @@ # Build for the abi-dumper (requires gcc) # Default=false # +# -DLIBICAL_DEVMODE_MEMORY_CONSISTENCY=[true|false] +# Build using special memory consistency versions of malloc(), realloc() and free() +# that perform some extra verifications. Most notably they ensure that memory allocated +# with icalmemory_new_buffer() is freed using icalmemory_free() rather than using free() +# directly and vice versa. Failing to do so would cause the test to fail with assertions +# or access violations. +# Default=false +# # -DADDRESS_SANITIZER=[true|false] # Build with the address sanitizer (requires gcc or clang) # Default=false @@ -537,6 +545,12 @@ if(ABI_DUMPER) endif() endif() +libical_option(LIBICAL_DEVMODE_MEMORY_CONSISTENCY "(Developer-only) Build with memory consistency functions." False) +if(LIBICAL_DEVMODE_MEMORY_CONSISTENCY) + add_definitions(-DMEMORY_CONSISTENCY) +endif() +mark_as_advanced(LIBICAL_DEVMODE_MEMORY_CONSISTENCY) + libical_option(ADDRESS_SANITIZER "(Developer-only) Build with the address sanitizer." False) mark_as_advanced(ADDRESS_SANITIZER) if(ADDRESS_SANITIZER) diff --git a/config.h.cmake b/config.h.cmake index 834dd7b1..e8796974 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -554,4 +554,4 @@ typedef ssize_t IO_SSIZE_T; #define ICALMEMORY_DEFAULT_MALLOC malloc #define ICALMEMORY_DEFAULT_REALLOC realloc -#define ICALMEMORY_DEFAULT_FREE free
\ No newline at end of file +#define ICALMEMORY_DEFAULT_FREE free diff --git a/src/libical/CMakeLists.txt b/src/libical/CMakeLists.txt index addd8343..441889d5 100644 --- a/src/libical/CMakeLists.txt +++ b/src/libical/CMakeLists.txt @@ -12,6 +12,9 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) +if(LIBICAL_DEVMODE_MEMORY_CONSISTENCY) + include_directories(${CMAKE_SOURCE_DIR}/src/test) +endif() if(ICU_FOUND) include_directories(${ICU_INCLUDE_DIRS}) @@ -243,6 +246,9 @@ set(ical_LIB_SRCS caldate.c astime.h ) +if(LIBICAL_DEVMODE_MEMORY_CONSISTENCY) + list(APPEND ical_LIB_SRCS ${PROJECT_SOURCE_DIR}/src/test/test-malloc.c) +endif() add_custom_command( OUTPUT diff --git a/src/libical/icalmemory.c b/src/libical/icalmemory.c index 722bdd2c..a1021ebe 100644 --- a/src/libical/icalmemory.c +++ b/src/libical/icalmemory.c @@ -33,6 +33,9 @@ #include "icalmemory.h" #include "icalerror.h" +#if defined(MEMORY_CONSISTENCY) +#include "test-malloc.h" +#endif #include <stdlib.h> @@ -281,19 +284,25 @@ char *icalmemory_strdup(const char *s) return res; } -#if defined(ICALMEMORY_DEFAULT_MALLOC) && !defined(S_SPLINT_S) +#if defined(MEMORY_CONSISTENCY) +static icalmemory_malloc_f global_icalmem_malloc = &test_malloc; +#elif defined(ICALMEMORY_DEFAULT_MALLOC) && !defined(S_SPLINT_S) static icalmemory_malloc_f global_icalmem_malloc = &ICALMEMORY_DEFAULT_MALLOC; #else static icalmemory_malloc_f global_icalmem_malloc = NULL; #endif -#if defined(ICALMEMORY_DEFAULT_REALLOC) && !defined(S_SPLINT_S) +#if defined(MEMORY_CONSISTENCY) +static icalmemory_realloc_f global_icalmem_realloc = &test_realloc; +#elif defined(ICALMEMORY_DEFAULT_REALLOC) && !defined(S_SPLINT_S) static icalmemory_realloc_f global_icalmem_realloc = &ICALMEMORY_DEFAULT_REALLOC; #else static icalmemory_realloc_f global_icalmem_realloc = NULL; #endif -#if defined(ICALMEMORY_DEFAULT_FREE) && !defined(S_SPLINT_S) +#if defined(MEMORY_CONSISTENCY) +static icalmemory_free_f global_icalmem_free = &test_free; +#elif defined(ICALMEMORY_DEFAULT_FREE) && !defined(S_SPLINT_S) static icalmemory_free_f global_icalmem_free = &ICALMEMORY_DEFAULT_FREE; #else static icalmemory_free_f global_icalmem_free = NULL; diff --git a/src/test/regression.c b/src/test/regression.c index be3a2a20..b32bc37b 100644 --- a/src/test/regression.c +++ b/src/test/regression.c @@ -5206,11 +5206,16 @@ int main(int argc, char *argv[]) int do_header = 0; int failed_count = 0; +#if !defined(MEMORY_CONSISTENCY) + // With MEMORY_CONSISTENCY we are building the entire library using the + // test_* functions; therefore, no need to set them here again. + // We specify special versions of malloc et al. that perform some extra verifications. // Most notably they ensure, that memory allocated with icalmemory_new_buffer() is freed // using icalmemory_free() rather than using free() directly and vice versa. Failing to // do so would cause the test to fail with assertions or access violations. icalmemory_set_mem_alloc_funcs(&test_malloc, &test_realloc, &test_free); +#endif set_zone_directory(TEST_ZONEDIR); icaltimezone_set_tzid_prefix(TESTS_TZID_PREFIX); diff --git a/src/test/test-malloc.c b/src/test/test-malloc.c index a54d91da..bc55af1c 100644 --- a/src/test/test-malloc.c +++ b/src/test/test-malloc.c @@ -20,7 +20,6 @@ FILE: test-malloc.c #endif #include "test-malloc.h" -#include "regression.h" #include <stdlib.h> #include <string.h> @@ -146,8 +145,8 @@ void test_free(void *p) { // icalmemory, e.g. via malloc(). // * The header in front of the memory block being freed has been corrupted. - ok("freed memory was allocated via icalmemory and has not been corrupted", - hdr->magic_no == TESTMALLOC_MAGIC_NO); + //ok("freed memory was allocated via icalmemory and has not been corrupted", + // hdr->magic_no == TESTMALLOC_MAGIC_NO); assert(hdr->magic_no == TESTMALLOC_MAGIC_NO); global_testmalloc_statistics.free_failed_cnt++; return; |