Skip to content

add proxy lib tests without LD_PRELOAD #1480

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
4 changes: 4 additions & 0 deletions .github/workflows/reusable_proxy_lib.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 1 addition & 10 deletions src/coarse/coarse.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -883,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");
Expand Down
11 changes: 3 additions & 8 deletions src/proxy_lib/proxy_lib_linux.c
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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();
}
21 changes: 21 additions & 0 deletions src/utils/utils_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,14 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>

#include <umf/base.h>
#include <umf/memory_provider.h>

#include "utils_load_library.h"

#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -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;
}

Expand Down
17 changes: 15 additions & 2 deletions src/utils/utils_load_library.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
16 changes: 15 additions & 1 deletion src/utils/utils_log.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 5 additions & 3 deletions test/utils/utils_log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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());
}
Expand Down Expand Up @@ -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";
}
}
Expand Down
Loading