I am using CUDA version 11.5 and want to utilize LD_PRELOAD
to hook APIs in libnvvm.so
to implement my own version. However, my interception attempt has not been successful.
I wrote the following code to intercept the nvvmAddModuleToProgram
function in libnvvm.so
:
nvcc.cpp:
#include "/usr/include/nvvm.h"
#include <dlfcn.h>
#include <filesystem>
#include <iostream>
#include <cstdio>
#include <list>
#include <string>
#include <sstream>
#include <vector>
#include <fstream>
#define LIBNVVM "libnvvm.so"
static void* libnvvm = NULL;
std::ofstream logFile("log.txt", std::ios::app);
#define bind_lib(lib) \
if (!libnvvm) { \
libnvvm = dlopen(lib, RTLD_NOW | RTLD_GLOBAL); \
if (!libnvvm) { \
fprintf(stderr, "Error loading %s: %s\n", lib, dlerror()); \
abort(); \
} \
}
#define bind_sym(handle, sym, retty, ...) \
typedef retty (*sym##_func_t)(__VA_ARGS__); \
static sym##_func_t sym##_real = NULL; \
if (!sym##_real) { \
sym##_real = (sym##_func_t)dlsym(handle, #sym); \
if (!sym##_real) { \
fprintf(stderr, "Error loading %s: %s\n", #sym, dlerror()); \
abort(); \
} \
}
nvvmResult nvvmAddModuleToProgram(nvvmProgram prog, const char *bitcode, size_t size, const char *name) {
logFile << "here" << std::endl;
bind_lib(LIBNVVM);
bind_sym(libnvvm, nvvmAddModuleToProgram, nvvmResult, nvvmProgram, const char*, size_t, const char*);
return nvvmAddModuleToProgram_real(prog, bitcode, size, name);
}
I compiled nvcc.cpp
into a shared library libnvcc.so
using the following command:
g++ -g -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -fPIC nvcc.cpp -shared -o libnvcc.so -ldl
Then, I executed the command:
LD_PRELOAD=/home/qzy/myfile/testcuda/libnvcc.so nvcc -o test test.cu -keep
I expected the nvvmAddModuleToProgram
function to hook the original function in libnvvm.so
, and if the hook was successful, it should print “here” in log.txt
. However, log.txt
remains empty, indicating that the hook has failed.
Could you please advise me on how to correctly hook the APIs in libnvvm.so
? Thank you!