summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt14
-rw-r--r--config.h.cmake2
-rw-r--r--src/libical/CMakeLists.txt6
-rw-r--r--src/libical/icalmemory.c15
-rw-r--r--src/test/regression.c5
-rw-r--r--src/test/test-malloc.c5
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;