From 57d9b0b49d75ae3f0873fb71ca2b340778758540 Mon Sep 17 00:00:00 2001 From: Rafal Rudnicki Date: Wed, 20 Aug 2025 09:17:58 +0000 Subject: [PATCH 1/4] add tests w/o proxy lib to reusable_proxy wflow --- .github/workflows/reusable_proxy_lib.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/reusable_proxy_lib.yml b/.github/workflows/reusable_proxy_lib.yml index 3c90678776..fbe4321d4a 100644 --- a/.github/workflows/reusable_proxy_lib.yml +++ b/.github/workflows/reusable_proxy_lib.yml @@ -54,6 +54,10 @@ jobs: - name: Build UMF run: cmake --build ${{env.BUILD_DIR}} -j $(nproc) + - name: Run "ctest --output-on-failure" without proxy library + working-directory: ${{env.BUILD_DIR}} + run: ctest --output-on-failure + - name: Run "ctest --output-on-failure" with proxy library working-directory: ${{env.BUILD_DIR}} run: LD_PRELOAD=./lib/libumf_proxy.so ctest --output-on-failure From 0f2870ed1536eccc3cd279419cdcb0d525301c57 Mon Sep 17 00:00:00 2001 From: Rafal Rudnicki Date: Wed, 20 Aug 2025 09:19:27 +0000 Subject: [PATCH 2/4] cleanup ctors/dtors and remove priorities --- src/coarse/coarse.c | 7 ------- src/proxy_lib/proxy_lib_linux.c | 11 +++-------- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/src/coarse/coarse.c b/src/coarse/coarse.c index a161ea5753..713015b84b 100644 --- a/src/coarse/coarse.c +++ b/src/coarse/coarse.c @@ -22,13 +22,6 @@ #include "utils_concurrency.h" #include "utils_log.h" -#ifdef _WIN32 -UTIL_ONCE_FLAG Log_initialized = UTIL_ONCE_FLAG_INIT; -#else -void __attribute__((constructor)) coarse_init(void) { utils_log_init(); } -void __attribute__((destructor)) coarse_destroy(void) {} -#endif /* _WIN32 */ - typedef struct coarse_t { // handle of the memory provider void *provider; diff --git a/src/proxy_lib/proxy_lib_linux.c b/src/proxy_lib/proxy_lib_linux.c index 50332b49f3..c9f44ef27a 100644 --- a/src/proxy_lib/proxy_lib_linux.c +++ b/src/proxy_lib/proxy_lib_linux.c @@ -1,6 +1,6 @@ /* * - * Copyright (C) 2024 Intel Corporation + * Copyright (C) 2024-2025 Intel Corporation * * Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception @@ -9,15 +9,10 @@ #include "proxy_lib.h" -// The priority 102 is used, because the constructor should be called as the second one -// (just after the first constructor of the base allocator with priority 101) -// and the destructor as the last but one (just before the last destructor -// of the base allocator with priority 101), because this library -// provides the memory allocation API. -void __attribute__((constructor(102))) proxy_lib_create(void) { +void __attribute__((constructor)) proxy_lib_create(void) { proxy_lib_create_common(); } -void __attribute__((destructor(102))) proxy_lib_destroy(void) { +void __attribute__((destructor)) proxy_lib_destroy(void) { proxy_lib_destroy_common(); } From 13bd6dd9deaba88e2c720ed23eccbffcb9316dd8 Mon Sep 17 00:00:00 2001 From: Rafal Rudnicki Date: Wed, 20 Aug 2025 09:20:43 +0000 Subject: [PATCH 3/4] initialize logger once (except tests) --- src/coarse/coarse.c | 4 +--- src/utils/utils_log.c | 16 +++++++++++++++- test/utils/utils_log.cpp | 8 +++++--- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/coarse/coarse.c b/src/coarse/coarse.c index 713015b84b..6019a1ac7f 100644 --- a/src/coarse/coarse.c +++ b/src/coarse/coarse.c @@ -876,9 +876,7 @@ static umf_result_t coarse_get_stats_no_lock(coarse_t *coarse, // PUBLIC API umf_result_t coarse_new(coarse_params_t *coarse_params, coarse_t **pcoarse) { -#ifdef _WIN32 - utils_init_once(&Log_initialized, utils_log_init); -#endif /* _WIN32 */ + utils_log_init(); if (coarse_params == NULL || pcoarse == NULL) { LOG_ERR("coarse parameters or handle is missing"); diff --git a/src/utils/utils_log.c b/src/utils/utils_log.c index 3c57ce033f..71669c282d 100644 --- a/src/utils/utils_log.c +++ b/src/utils/utils_log.c @@ -32,6 +32,10 @@ #include "utils_common.h" #include "utils_log.h" +#ifndef DISABLE_SINGLE_LOGGER +#include "utils_concurrency.h" +#endif + #define UMF_MAGIC_STR "\x00@(#) " #define UMF_PREF_STR "Intel(R) " #define UMF_PREFIX UMF_MAGIC_STR UMF_PREF_STR @@ -60,6 +64,10 @@ char const __umf_str_1__all_cmake_vars[] = #define MAX_FILE_PATH 256 #define MAX_ENV_LEN 2048 +#ifndef DISABLE_SINGLE_LOGGER +static UTIL_ONCE_FLAG initOnce = UTIL_ONCE_FLAG_INIT; +#endif + typedef struct { bool enableTimestamp; bool enablePid; @@ -247,7 +255,7 @@ void utils_plog(utils_log_level_t level, const char *func, const char *format, static const char *bool_to_str(int b) { return b ? "yes" : "no"; } -void utils_log_init(void) { +static void utils_log_init_once(void) { const char *envVar = getenv("UMF_LOG"); if (!envVar) { @@ -343,6 +351,12 @@ void utils_log_init(void) { } // this is needed for logger unit test +#ifndef DISABLE_SINGLE_LOGGER +void utils_log_init(void) { utils_init_once(&initOnce, utils_log_init_once); } +#else +void utils_log_init(void) { utils_log_init_once(); } +#endif + #ifndef DISABLE_CTL_LOGGER static umf_result_t CTL_READ_HANDLER(timestamp)(void *ctx, umf_ctl_query_source_t source, void *arg, diff --git a/test/utils/utils_log.cpp b/test/utils/utils_log.cpp index 4d1b0554eb..3c7992bbc8 100644 --- a/test/utils/utils_log.cpp +++ b/test/utils/utils_log.cpp @@ -97,6 +97,7 @@ int mock_strerror_windows(char *buff, size_t s, int errnum) { extern "C" { #define DISABLE_CTL_LOGGER 1 +#define DISABLE_SINGLE_LOGGER 1 const char *env_variable = ""; #define fopen(A, B) mock_fopen(A, B) #define fputs(A, B) mock_fputs(A, B) @@ -161,8 +162,8 @@ TEST_F(test, parseEnv_errors) { helper_checkConfig(&b, &loggerConfig); helper_log_init("_level:debug"); helper_checkConfig(&b, &loggerConfig); - expected_message = - "[ERROR UMF] utils_log_init: Cannot open output file - path too long\n"; + expected_message = "[ERROR UMF] utils_log_init_once: Cannot open output " + "file - path too long\n"; std::string test_env = "output:file," + std::string(300, 'x'); helper_log_init(test_env.c_str()); } @@ -247,7 +248,8 @@ TEST_F(test, parseEnv) { expect_fput_count = 1; if (expected_filename.size() > MAX_FILE_PATH) { expected_message = - "[ERROR UMF] utils_log_init: Cannot open " + "[ERROR UMF] utils_log_init_once: Cannot " + "open " "output file - path too long\n"; } } From 220aa29b8604351c9a1416ecbd12cd2dea475c03 Mon Sep 17 00:00:00 2001 From: Rafal Rudnicki Date: Wed, 20 Aug 2025 10:11:05 +0000 Subject: [PATCH 4/4] do not destroy proxy lib pool before umf lib --- src/utils/utils_common.h | 21 +++++++++++++++++++++ src/utils/utils_load_library.c | 17 +++++++++++++++-- 2 files changed, 36 insertions(+), 2 deletions(-) diff --git a/src/utils/utils_common.h b/src/utils/utils_common.h index 17dd006ad6..df8536cfb4 100644 --- a/src/utils/utils_common.h +++ b/src/utils/utils_common.h @@ -14,10 +14,14 @@ #include #include #include +#include +#include #include #include +#include "utils_load_library.h" + #ifdef __cplusplus extern "C" { #endif @@ -79,6 +83,23 @@ static inline int utils_env_var_has_str(const char *envvar, const char *str) { // check if we are running in the proxy library static inline int utils_is_running_in_proxy_lib(void) { + // check if the proxy library is loaded using /proc/self/maps + FILE *fp = fopen("/proc/self/maps", "r"); + if (!fp) { + perror("Failed to open /proc/self/maps"); + return -1; + } + + char line[256]; + while (fgets(line, sizeof(line), fp)) { + if (strstr(line, "libumf_proxy.so") != NULL) { + fclose(fp); + return 1; // Shared object is loaded + } + } + fclose(fp); + + // check if the proxy library is loaded using LD_PRELOAD return utils_env_var_get_str("LD_PRELOAD", "libumf_proxy.so") ? 1 : 0; } diff --git a/src/utils/utils_load_library.c b/src/utils/utils_load_library.c index d774fec840..3de0b34715 100644 --- a/src/utils/utils_load_library.c +++ b/src/utils/utils_load_library.c @@ -71,18 +71,31 @@ void *utils_open_library(const char *filename, int userFlags) { dlopenFlags |= RTLD_GLOBAL; } if (userFlags & UMF_UTIL_OPEN_LIBRARY_NO_LOAD) { - dlopenFlags |= RTLD_NOLOAD; + dlopenFlags = RTLD_NOLOAD | RTLD_NOW; } void *handle = dlopen(filename, dlopenFlags); if (handle == NULL) { + if (userFlags & UMF_UTIL_OPEN_LIBRARY_NO_LOAD) { + // if we are not loading the library, just return NULL if it is not + // found + LOG_DEBUG("Library %s not found, returning NULL", filename); + return NULL; + } + LOG_FATAL("dlopen(%s) failed with error: %s", filename, dlerror()); + return NULL; } + LOG_DEBUG("Opened library %s with handle %p", filename, handle); return handle; } -int utils_close_library(void *handle) { return dlclose(handle); } +int utils_close_library(void *handle) { + LOG_DEBUG("Closing library handle %p", handle); + + return dlclose(handle); +} void *utils_get_symbol_addr(void *handle, const char *symbol, const char *libname) {