From b3f922c35c9d7a7e15b0a70b0d0526aac7023da8 Mon Sep 17 00:00:00 2001 From: Basile Desloges <basile.desloges@cea.fr> Date: Tue, 9 Nov 2021 16:03:02 +0100 Subject: [PATCH] [eacsl] Add locks for RTL log printing --- .../instrumentation_model/e_acsl_assert.c | 6 +++++ .../share/e-acsl/internals/e_acsl_debug.c | 2 ++ .../share/e-acsl/internals/e_acsl_rtl_io.c | 24 +++++++++++++++++++ .../share/e-acsl/internals/e_acsl_rtl_io.h | 17 +++++++++++++ .../share/e-acsl/internals/e_acsl_trace.c | 2 ++ .../internals/e_acsl_patricia_trie.c | 2 ++ .../segment_model/e_acsl_segment_tracking.c | 4 ++++ .../segment_model/e_acsl_shadow_concurrency.c | 2 ++ 8 files changed, 59 insertions(+) diff --git a/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.c b/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.c index b2b3ad1e9e3..0d1158d3b7b 100644 --- a/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.c +++ b/src/plugins/e-acsl/share/e-acsl/instrumentation_model/e_acsl_assert.c @@ -50,6 +50,7 @@ void eacsl_print_values(eacsl_assert_data_t *data) { void eacsl_runtime_assert(int predicate, eacsl_assert_data_t *data) { if (eacsl_runtime_sound_verdict) { if (!predicate) { + RTL_IO_LOCK(); // clang-format off STDERR("%s: In function '%s'\n" "%s:%d: Error: %s failed:\n" @@ -60,6 +61,7 @@ void eacsl_runtime_assert(int predicate, eacsl_assert_data_t *data) { data->pred_txt); // clang-format on eacsl_print_values(data); + RTL_IO_UNLOCK(); if (data->blocking) { # ifndef E_ACSL_NO_ASSERT_FAIL /* Do fail on assertions */ # ifdef E_ACSL_FAIL_EXITCODE /* Fail by exit with a given code */ @@ -72,6 +74,7 @@ void eacsl_runtime_assert(int predicate, eacsl_assert_data_t *data) { } # ifdef E_ACSL_DEBUG_ASSERT else { + RTL_IO_LOCK(); // clang-format off STDERR("%s: In function '%s'\n" "%s:%d: %s valid:\n" @@ -81,9 +84,11 @@ void eacsl_runtime_assert(int predicate, eacsl_assert_data_t *data) { data->pred_txt); // clang-format on eacsl_print_values(data); + RTL_IO_UNLOCK(); } # endif } else { + RTL_IO_LOCK(); // clang-format off STDERR("%s: In function '%s'\n" "%s:%d: Warning: no sound verdict for %s (guess: %s).\n" @@ -94,6 +99,7 @@ void eacsl_runtime_assert(int predicate, eacsl_assert_data_t *data) { data->pred_txt); // clang-format on eacsl_print_values(data); + RTL_IO_UNLOCK(); } } #endif diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_debug.c b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_debug.c index 9e7ee446a82..15ce0534410 100644 --- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_debug.c +++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_debug.c @@ -88,6 +88,7 @@ void initialize_report_file(int *argc, char ***argv) { void describe_run() { #if defined(E_ACSL_VERBOSE) + RTL_IO_LOCK(); rtl_printf( "/* ========================================================= */\n"); rtl_printf(" * E-ACSL instrumented run\n"); @@ -99,5 +100,6 @@ void describe_run() { rtl_printf(" * Format Checks: %s\n", E_ACSL_FORMAT_VALIDITY_DESC); rtl_printf( "/* ========================================================= */\n"); + RTL_IO_UNLOCK(); #endif } diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_rtl_io.c b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_rtl_io.c index 45bfaacbd04..78989ecd128 100644 --- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_rtl_io.c +++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_rtl_io.c @@ -45,6 +45,7 @@ #include <stdint.h> #include <unistd.h> +#include "e_acsl_concurrency.h" #include "e_acsl_rtl_io.h" /*! \brief Test if we can still write `n + 1` characters to the buffer according @@ -68,6 +69,23 @@ typedef void (*putcf)(void *, size_t *, char); +#ifdef E_ACSL_CONCURRENCY_PTHREAD +static pthread_mutex_t rtl_io_global_mutex_value; + +static void rtl_io_initialize_global_mutex() { + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&rtl_io_global_mutex_value, &attr); + pthread_mutexattr_destroy(&attr); +} + +pthread_mutex_t *rtl_io_global_mutex() { + E_ACSL_RUN_ONCE(rtl_io_initialize_global_mutex); + return &rtl_io_global_mutex_value; +} +#endif + /* Unsigned long integers to string conversion (%u) */ static void uli2a(unsigned long int num, unsigned int base, int uc, char *bf) { int n = 0; @@ -424,7 +442,9 @@ int rtl_printf(char *fmt, ...) { } int rtl_vprintf(char *fmt, va_list vlist) { + RTL_IO_LOCK(); _format(NULL, NULL, _charc_stdout, fmt, vlist); + RTL_IO_UNLOCK(); return 1; } @@ -437,7 +457,9 @@ int rtl_eprintf(char *fmt, ...) { } int rtl_veprintf(char *fmt, va_list vlist) { + RTL_IO_LOCK(); _format(NULL, NULL, _charc_stderr, fmt, vlist); + RTL_IO_UNLOCK(); return 1; } @@ -450,8 +472,10 @@ int rtl_dprintf(int fd, char *fmt, ...) { } int rtl_vdprintf(int fd, char *fmt, va_list vlist) { + RTL_IO_LOCK(); intptr_t fd_long = fd; _format((void *)fd_long, NULL, _charc_file, fmt, vlist); + RTL_IO_UNLOCK(); return 1; } diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_rtl_io.h b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_rtl_io.h index f26a145efd2..779bc360524 100644 --- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_rtl_io.h +++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_rtl_io.h @@ -77,6 +77,23 @@ #define STDOUT(...) rtl_printf(__VA_ARGS__) #define STDERR(...) rtl_eprintf(__VA_ARGS__) +#ifdef E_ACSL_CONCURRENCY_PTHREAD +# include <pthread.h> + +/*! \brief Returns the global mutex for RTL printing. This mutex is recursive so + multiple locks can be acquired from the same thread. */ +pthread_mutex_t *rtl_io_global_mutex(); + +/*! \brief Lock the global RTL printing mutex. */ +# define RTL_IO_LOCK() pthread_mutex_lock(rtl_io_global_mutex()); + +/*! \brief Unlock the global RTL printing mutex. */ +# define RTL_IO_UNLOCK() pthread_mutex_unlock(rtl_io_global_mutex()); +#else +# define RTL_IO_LOCK() +# define RTL_IO_UNLOCK() +#endif + /* Replacement for printf with support for the above specifiers */ int rtl_printf(char *fmt, ...); int rtl_vprintf(char *fmt, va_list vlist); diff --git a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_trace.c b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_trace.c index 60888729cb2..631322b9826 100644 --- a/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_trace.c +++ b/src/plugins/e-acsl/share/e-acsl/internals/e_acsl_trace.c @@ -77,6 +77,7 @@ static int native_backtrace(void **array, int size) { void trace() { #if E_ACSL_OS_IS_LINUX + RTL_IO_LOCK(); int size = 24; void **bb = private_malloc(sizeof(void *) * size); @@ -112,5 +113,6 @@ void trace() { counter++; } STDERR("/***************************************/\n"); + RTL_IO_UNLOCK(); #endif /* E_ACSL_OS_IS_LINUX */ } diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_patricia_trie.c b/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_patricia_trie.c index 816b086f859..4872e5ce2bf 100644 --- a/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_patricia_trie.c +++ b/src/plugins/e-acsl/share/e-acsl/observation_model/internals/e_acsl_patricia_trie.c @@ -606,6 +606,7 @@ static void pt_print_node(const pt_struct_t *pt, pt_node_t *node, int depth) { } void pt_print(const pt_struct_t *pt) { + RTL_IO_LOCK(); DLOG("------------DEBUG\n"); if (pt != NULL) { E_ACSL_RLOCK(pt->lock); @@ -615,5 +616,6 @@ void pt_print(const pt_struct_t *pt) { DLOG("Patricia trie is NULL\n"); } DLOG("-----------------\n"); + RTL_IO_UNLOCK(); } #endif // E_ACSL_DEBUG diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.c b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.c index add2d3db74d..f1f378fd017 100644 --- a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.c +++ b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_segment_tracking.c @@ -1111,10 +1111,12 @@ void print_heap_shadows(uintptr_t addr) { } void print_shadows(uintptr_t addr, size_t size) { + RTL_IO_LOCK(); if (IS_ON_STATIC(addr)) print_static_shadows(addr, size); else if (IS_ON_HEAP(addr)) print_heap_shadows(addr); + RTL_IO_UNLOCK(); } void print_memory_segment(struct memory_segment *p, char *lab, int off) { @@ -1147,6 +1149,7 @@ void print_memory_partition(struct memory_partition *p) { } void print_shadow_layout() { + RTL_IO_LOCK(); DLOG(">>> HEAP ---------------------\n"); print_memory_partition(&mem_layout.heap); DLOG(">>> STACK --------------------\n"); @@ -1171,6 +1174,7 @@ void print_shadow_layout() { print_memory_partition(&mem_layout.rdata); # endif DLOG(">>> --------------------------\n"); + RTL_IO_UNLOCK(); } const char *which_segment(uintptr_t addr) { diff --git a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_concurrency.c b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_concurrency.c index 7ac2d7d13bd..042eef56fbc 100644 --- a/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_concurrency.c +++ b/src/plugins/e-acsl/share/e-acsl/observation_model/segment_model/e_acsl_shadow_concurrency.c @@ -213,10 +213,12 @@ void init_thread_shadow_layout(size_t stack_size) { pt_insert(thread_partitions, (pt_leaf_t)tls); # if defined(E_ACSL_DEBUG) && defined(E_ACSL_DEBUG_VERBOSE) + RTL_IO_LOCK(); DLOG(">>> Thread stack -------------\n"); print_memory_partition(&stack->p); DLOG(">>> Thread TLS ---------------\n"); print_memory_partition(&tls->p); + RTL_IO_UNLOCK(); # endif // Safe location tracking for thread-specific locations -- GitLab