Skip to content

Commit

Permalink
make LD_PRELOAD style of DLIO Profiler.
Browse files Browse the repository at this point in the history
  • Loading branch information
hariharan-devarajan committed Oct 5, 2023
1 parent e81d135 commit 8de2d12
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 109 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,7 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
set(DLIO_PROFILER_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/brahma/posix.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/brahma/stdio.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/dlio_profiler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/include/dlio_profiler/dlio_profiler.h
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/dlio_profiler.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/writer/chrome_writer.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/utils/posix_internal.cpp)
set(DLIO_PROFILER_PUBLIC_INCLUDE
Expand All @@ -147,6 +146,7 @@ set(DLIO_PROFILER_PUBLIC_INCLUDE
${CMAKE_CURRENT_SOURCE_DIR}/include/dlio_profiler/dlio_profiler.h)
set(DLIO_PROFILER_PRIVATE_INCLUDE
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/dlio_logger.h
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/core/dlio_profiler_main.h
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/core/constants.h
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/utils/posix_internal.h
${CMAKE_CURRENT_SOURCE_DIR}/src/dlio_profiler/utils/utils.h)
Expand Down
2 changes: 1 addition & 1 deletion include/dlio_profiler/dlio_profiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
//

#ifndef DLIO_PROFILER_DLIO_PROFILER_H
#define DLIO_PROFILER_DLIO_PROFILER_H
#define DLIO_PROFILER_DLIO_PROFILER_LIB_H
#include <brahma/brahma.h>
#include <dlio_profiler/brahma/posix.h>
#include <dlio_profiler/brahma/stdio.h>
Expand Down
13 changes: 13 additions & 0 deletions src/dlio_profiler/core/constants.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// Created by haridev on 10/5/23.
//

#ifndef DLIO_PROFILER_CONSTANTS_H
#define DLIO_PROFILER_CONSTANTS_H
#define DLIO_PROFILER_ENABLE "DLIO_PROFILER_ENABLE"
#define DLIO_PROFILER_GOTCHA_PRIORITY "DLIO_PROFILER_GOTCHA_PRIORITY"
#define DLIO_PROFILER_LOG_LEVEL "DLIO_PROFILER_LOG_LEVEL"
#define DLIO_PROFILER_LOG_FILE "DLIO_PROFILER_LOG_FILE"
#define DLIO_PROFILER_INIT "DLIO_PROFILER_INIT"
#define DLIO_PROFILER_DATA_DIR "DLIO_PROFILER_DATA_DIR"
#endif //DLIO_PROFILER_CONSTANTS_H
132 changes: 132 additions & 0 deletions src/dlio_profiler/core/dlio_profiler_main.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
//
// Created by haridev on 10/5/23.
//

#ifndef DLIO_PROFILER_DLIO_PROFILER_MAIN_H
#define DLIO_PROFILER_DLIO_PROFILER_MAIN_H
#include <cstring>
#include <thread>
#include <stdexcept>

#include <cpp-logger/logger.h>
#include <dlio_profiler/core/constants.h>
#include <dlio_profiler/macro.h>
#include <dlio_profiler/brahma/posix.h>
#include <dlio_profiler/brahma/stdio.h>
#include <dlio_profiler/dlio_logger.h>
#include <brahma/brahma.h>
#include <execinfo.h>
#include "singleton.h"

static void handler(int sig) {
void *array[10];
size_t size;

// get void*'s for all entries on the stack
size = backtrace(array, 10);

// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}

namespace dlio_profiler {
class DLIOProfiler {
private:
bool is_enabled;
int gotcha_priority;
cpplogger::LoggerType logger_level;
char* log_file;
char* data_dirs;
int process_id;
bool is_init;
public:
DLIOProfiler(bool is_init, const char *log_file = nullptr, const char *data_dirs = nullptr, const int *process_id = nullptr) : is_enabled(
false), gotcha_priority(1), logger_level(cpplogger::LoggerType::LOG_ERROR), log_file(nullptr), data_dirs(
nullptr), is_init(is_init) {
signal(SIGSEGV, handler);
if (this->is_init) {
char *dlio_profiler_enable = getenv(DLIO_PROFILER_ENABLE);
if (dlio_profiler_enable != nullptr && strcmp(dlio_profiler_enable, "1") == 0) {
is_enabled = true;
}
if (is_enabled) {
char *dlio_profiler_priority_str = getenv(DLIO_PROFILER_GOTCHA_PRIORITY);
if (dlio_profiler_priority_str != nullptr) {
gotcha_priority = atoi(dlio_profiler_priority_str);
}
char *dlio_profiler_log_level = getenv(DLIO_PROFILER_LOG_LEVEL);
if (dlio_profiler_log_level == nullptr) {
logger_level = cpplogger::LoggerType::LOG_ERROR;
} else {
if (strcmp(dlio_profiler_log_level, "ERROR") == 0) {
logger_level = cpplogger::LoggerType::LOG_ERROR;
} else if (strcmp(dlio_profiler_log_level, "INFO") == 0) {
logger_level = cpplogger::LoggerType::LOG_INFO;
} else if (strcmp(dlio_profiler_log_level, "DEBUG") == 0) {
logger_level = cpplogger::LoggerType::LOG_WARN;
}
}
DLIO_PROFILER_LOGGER->level = logger_level;
DLIO_PROFILER_LOGINFO("Enabling logging level %d", logger_level);

if (log_file == nullptr) {
char *dlio_profiler_log = getenv(DLIO_PROFILER_LOG_FILE);
if (dlio_profiler_log != nullptr) {
this->log_file = dlio_profiler_log;
} else {
const char *message = "log_file not defined. Please define env variable DLIO_PROFILER_LOG_FILE";
DLIO_PROFILER_LOGERROR(message, "");
throw std::runtime_error(message);
}
}

if (data_dirs == nullptr) {
char *dlio_profiler_data_dirs = getenv(DLIO_PROFILER_DATA_DIR);
if (dlio_profiler_data_dirs != nullptr) {
this->data_dirs = dlio_profiler_data_dirs;
} else {
const char *message = "data_dirs not defined. Please define env variable DLIO_PROFILER_DATA_DIR";
DLIO_PROFILER_LOGERROR(message, "");
throw std::runtime_error(message);
}
}

if (process_id == nullptr) {
this->process_id = getpid();
} else {
this->process_id = *process_id;
}

dlio_profiler::Singleton<DLIOLogger>::get_instance()->update_log_file(this->log_file, this->process_id);
brahma_gotcha_wrap("dlio_profiler", this->gotcha_priority);
auto posix_instance = brahma::POSIXDLIOProfiler::get_instance();
auto stdio_instance = brahma::STDIODLIOProfiler::get_instance();
auto paths = split(this->data_dirs, ':');
posix_instance->untrace(this->log_file);
stdio_instance->untrace(this->log_file);
for (const auto &path:paths) {
DLIO_PROFILER_LOGINFO("Profiler will trace %s\n", path.c_str());
posix_instance->trace(path.c_str());
stdio_instance->trace(path.c_str());
}
size_t thread_hash = std::hash<std::thread::id>{}(std::this_thread::get_id());
DLIO_PROFILER_LOGINFO("Running DLIO Profiler on thread %ld and pid %ld", thread_hash, this->process_id);
}
}
}
bool finalize() {
if (is_init && is_enabled) {
DLIO_PROFILER_LOGINFO("Calling finalize", "");
dlio_profiler::Singleton<DLIOLogger>::get_instance(false)->finalize();
free_bindings();
return true;
}
return false;
}
};
} // namespace dlio_profiler


#endif //DLIO_PROFILER_DLIO_PROFILER_MAIN_H
8 changes: 8 additions & 0 deletions src/dlio_profiler/core/error.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
//
// Created by haridev on 10/5/23.
//

#ifndef DLIO_PROFILER_ERROR_H
#define DLIO_PROFILER_ERROR_H

#endif //DLIO_PROFILER_ERROR_H
74 changes: 10 additions & 64 deletions src/dlio_profiler/dlio_profiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,82 +9,28 @@
#include<algorithm>
#include <dlio_profiler/dlio_logger.h>
#include <dlio_profiler/utils/utils.h>
#include <dlio_profiler/core/constants.h>
#include <dlio_profiler/core/dlio_profiler_main.h>

namespace dlio_profiler {
bool init = false;
}

bool is_init() {return dlio_profiler::init;}
void set_init(bool _init) { dlio_profiler::init = _init;}
void dlio_profiler_init(void) {
bool init_log = false;
char *ld_preload = getenv("LD_PRELOAD");
if (ld_preload != nullptr && std::string(ld_preload).find("libdlio_profiler.so") != std::string::npos) {
init_log = true;
}
if (!is_init()) {
char *dlio_profiler_enable = getenv("DLIO_PROFILER_ENABLE");
if (dlio_profiler_enable == nullptr || strcmp(dlio_profiler_enable, "1") == 0) {
char *dlio_profiler_debug = getenv("DLIO_PROFILER_DEBUG");
if (dlio_profiler_debug != nullptr) {
if (strcmp(dlio_profiler_debug, "1") == 0) {
std::string sp;
std::ifstream("/proc/self/cmdline") >> sp;
std::replace(sp.begin(), sp.end() - 1, '\000', ' ');
fprintf(stderr, "Connect to pid %d %s\n", getpid(), sp.c_str());
fflush(stderr);
getchar();
}
}
DLIO_PROFILER_LOGINFO("constructor", "");
char *dlio_profiler_log_level = getenv("DLIO_PROFILER_LOG_LEVEL");
if (dlio_profiler_log_level == nullptr) {
DLIO_PROFILER_LOGGER->level = cpplogger::LoggerType::LOG_ERROR;
DLIO_PROFILER_LOGINFO("Enabling ERROR loggin", "");
} else {
if (strcmp(dlio_profiler_log_level, "ERROR") == 0) {
DLIO_PROFILER_LOGGER->level = cpplogger::LoggerType::LOG_ERROR;
DLIO_PROFILER_LOGINFO("Enabling ERROR loggin", "");
} else if (strcmp(dlio_profiler_log_level, "INFO") == 0) {
DLIO_PROFILER_LOGGER->level = cpplogger::LoggerType::LOG_INFO;
DLIO_PROFILER_LOGINFO("Enabling INFO loggin", "");
} else if (strcmp(dlio_profiler_log_level, "DEBUG") == 0) {
DLIO_PROFILER_LOGINFO("Enabling DEBUG loggin", "");
DLIO_PROFILER_LOGGER->level = cpplogger::LoggerType::LOG_WARN;
}
}
char *dlio_profiler_priority_str = getenv("DLIO_PROFILER_GOTCHA_PRIORITY");
int dlio_profiler_priority = 1;
if (dlio_profiler_priority_str != nullptr) {
dlio_profiler_priority = atoi(dlio_profiler_priority_str);
}
/*
dlio_profiler::Singleton<DLIOLogger>::get_instance(init_log);
brahma_gotcha_wrap("dlio_profiler", dlio_profiler_priority);
auto posix_instance = brahma::POSIXDLIOProfiler::get_instance();
auto stdio_instance = brahma::STDIODLIOProfiler::get_instance();
char *dlio_profiler_dir = getenv("DLIO_PROFILER_DIR");
if (dlio_profiler_dir != nullptr) {
auto paths = split(dlio_profiler_dir, ':');
for (const auto &path:paths) {
DLIO_PROFILER_LOGINFO("Profiler will trace %s\n", path.c_str());
posix_instance->trace(path);
stdio_instance->trace(path);
}
}
*/
}
char *init_type = getenv(DLIO_PROFILER_INIT);
if (!is_init() && init_type != nullptr && strcmp(init_type, "PRELOAD") == 0) {
dlio_profiler::Singleton<dlio_profiler::DLIOProfiler>::get_instance(true);
DLIO_PROFILER_LOGINFO("Running initialize within constructor", "");
set_init(true);
}
size_t thread_hash = std::hash<std::thread::id>{}(std::this_thread::get_id());
DLIO_PROFILER_LOGINFO("Running DLIO Profiler on thread %ld and pid %ld", thread_hash, getpid());

}
void dlio_profiler_fini(void) {
if (is_init()) {
char *dlio_profiler_init = getenv("DLIO_PROFILER_INIT");
if (dlio_profiler_init == nullptr || strcmp(dlio_profiler_init, "1") == 0) {
free_bindings();
}
char *init_type = getenv(DLIO_PROFILER_INIT);
if (is_init() && init_type != nullptr && strcmp(init_type, "PRELOAD")) {
dlio_profiler::Singleton<dlio_profiler::DLIOProfiler>::get_instance(false)->finalize();
set_init(false);
}
}
42 changes: 9 additions & 33 deletions src/dlio_profiler/dlio_profiler_py.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@

#include <dlio_profiler/dlio_logger.h>
#include <pybind11/pybind11.h>
#include <dlio_profiler/brahma/posix.h>
#include <dlio_profiler/brahma/stdio.h>
#include <dlio_profiler/utils/utils.h>
#include <pybind11/stl.h>
#include <iostream>
Expand All @@ -14,42 +12,18 @@
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <dlio_profiler/core/constants.h>
#include <dlio_profiler/core/dlio_profiler_main.h>

namespace py = pybind11;
namespace dlio_profiler {


void handler(int sig) {
void *array[10];
size_t size;

// get void*'s for all entries on the stack
size = backtrace(array, 10);

// print out all the frames to stderr
fprintf(stderr, "Error: signal %d:\n", sig);
backtrace_symbols_fd(array, size, STDERR_FILENO);
exit(1);
}
void initialize(std::string &log_file, std::string &data_dirs, int process_id) {
signal(SIGSEGV, handler);
if (process_id <= 0) DLIO_PROFILER_LOGPRINT("log_file %s data_dirs %s and process %d\n", log_file.c_str(), data_dirs.c_str(), process_id);
dlio_profiler::Singleton<DLIOLogger>::get_instance()->update_log_file(log_file, process_id);
char *dlio_profiler_priority_str = getenv("DLIO_PROFILER_GOTCHA_PRIORITY");
int dlio_profiler_priority = 1;
if (dlio_profiler_priority_str != nullptr) {
dlio_profiler_priority = atoi(dlio_profiler_priority_str);
}
brahma_gotcha_wrap("dlio_profiler", dlio_profiler_priority);
auto posix_instance = brahma::POSIXDLIOProfiler::get_instance();
auto stdio_instance = brahma::STDIODLIOProfiler::get_instance();
auto paths = split(data_dirs, ':');
posix_instance->untrace(log_file.c_str());
stdio_instance->untrace(log_file.c_str());
for (const auto &path:paths) {
DLIO_PROFILER_LOGINFO("Profiler will trace %s\n", path.c_str());
posix_instance->trace(path.c_str());
stdio_instance->trace(path.c_str());
char *init_type = getenv(DLIO_PROFILER_INIT);
if (init_type == nullptr || strcmp(init_type, "FUNCTION") == 0) {
dlio_profiler::Singleton<dlio_profiler::DLIOProfiler>::get_instance(true, log_file.c_str(), data_dirs.c_str(), &process_id);
}
}
TimeResolution get_time() {
Expand All @@ -66,8 +40,10 @@ namespace dlio_profiler {
dlio_profiler::Singleton<DLIOLogger>::get_instance(false)->log(name, cat, start_time, duration, args);
}
void finalize() {
DLIO_PROFILER_LOGINFO("Calling finalize", "");
dlio_profiler::Singleton<DLIOLogger>::get_instance(false)->finalize();
char *init_type = getenv(DLIO_PROFILER_INIT);
if (init_type == nullptr || strcmp(init_type, "FUNCTION") == 0) {
dlio_profiler::Singleton<dlio_profiler::DLIOProfiler>::get_instance(false)->finalize();
}
}
} // dlio_profiler
PYBIND11_MODULE(dlio_profiler_py, m) {
Expand Down
17 changes: 8 additions & 9 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@

set(TEST_BASIC_SRC test.cpp)
add_executable(test_basic ${TEST_BASIC_SRC})
add_executable(test_basic test.cpp)
add_dependencies(test_basic ${PROJECT_NAME})
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/data)
file(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/log)
add_test(test ${CMAKE_BINARY_DIR}/bin/test_basic ${CMAKE_BINARY_DIR}/data/file.dat)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/data)
add_test(test ${CMAKE_BINARY_DIR}/bin/test_basic)
set_property(TEST test APPEND PROPERTY ENVIRONMENT LD_PRELOAD=${CMAKE_BINARY_DIR}/lib/libdlio_profiler.so)
set_property(TEST test APPEND PROPERTY ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib)
set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_DIR=${CMAKE_BINARY_DIR}/data)
set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_LOG_DIR=${CMAKE_SOURCE_DIR}/log)
set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_ENABLE=1)
set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_INIT=PRELOAD)
set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_DATA_DIR=${CMAKE_CURRENT_BINARY_DIR}/data)
set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_LOG_FILE=${CMAKE_BINARY_DIR}/log_cpp.pwf)
set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_LOG_LEVEL=INFO)

find_program(PYTHON_EXE python)
message("-- Found python at location " ${PYTHON_EXE})
add_test(test_py ${PYTHON_EXE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/test/data)
set_property(TEST test_py APPEND PROPERTY ENVIRONMENT PYTHONPATH=$ENV{PYTHONPATH}:${CMAKE_SOURCE_DIR}/venv/lib)
set_property(TEST test_py APPEND PROPERTY ENVIRONMENT LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/lib:${CMAKE_SOURCE_DIR}/dependency/.spack-env/view/lib64)
set_property(TEST test APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_ENABLE=1)
set_property(TEST test_py APPEND PROPERTY ENVIRONMENT DLIO_PROFILER_LOG_LEVEL=INFO)
3 changes: 3 additions & 0 deletions test/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@

#include <string>
int main(int argc, char* argv[]) {
FILE* fh = fopen("./data/demofile.txt", "w+");
fwrite("hello", sizeof("hello"), 1, fh);
fclose(fh);
return 0;
}

0 comments on commit 8de2d12

Please sign in to comment.