[英]dlsym causing segfault when dynamically loading shm_open
我试图找出在运行时动态加载 function shm_open
并遇到了困难。
我当前的代码是这样的:
CMakeLists.txt
project(dlsysm_stack_overflow_example)
cmake_minimum_required(VERSION 3.16)
add_executable(${PROJECT_NAME}
main.cpp
custom_mman.cpp
)
target_link_libraries(${PROJECT_NAME}
dl
)
custom_mman.cpp
#include <iostream>
#define _GNU_SOURCE
#include <dlfcn.h>
extern "C"
{
int shm_open(const char* name, int oflag, mode_t mode)
{
using ShmOpenFuncPtr_t = int (*)(const char*, int, mode_t);
static ShmOpenFuncPtr_t real_shm_open = nullptr;
std::cout << "custom shm_open\n";
if (nullptr == real_shm_open)
{
real_shm_open = reinterpret_cast<ShmOpenFuncPtr_t>(dlsym(RTLD_NEXT, "shm_open"));
char* error = dlerror();
if (error != nullptr)
{
std::cout << "could not load shm_open at runtime! error: " << error << "\n";
return -1;
}
}
return real_shm_open(name, oflag, mode);
}
}
主.cpp
#include <sys/mman.h>
#include <fcntl.h>
#include <iostream>
int main(int argc, char** argv)
{
int return_value = shm_open("/shm_name", O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
std::cout << "return_value: " << return_value << "\n";
return 0;
}
目前,因为我为可执行文件提供了custom_mann.cpp
源文件,所以 linker 在标准库定义之前找到了我对shm_open
的定义并改为调用它。 我的意图是在调用真正的shm_open
function 之前做一些逻辑。
但是,对dlsym
的调用返回一个 null 指针,因此当调用real_shm_open
时,会发生段错误。 奇怪的是, dlerror
没有设置错误代码,所以如果dlsym
没有返回正确的指针,function 不会像我预期的那样提前返回。
非常感谢为什么会发生这种情况的任何想法?
shm_open
由librt.so
提供。 根据Linux shm_open()
手册页(加粗我的):
名称
shm_open, shm_unlink - 创建/打开或取消链接 POSIX 共享的 memory 个对象
概要
#include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants */ int shm_open(const char *name, int oflag, mode_t mode); int shm_unlink(const char *name);
与
-lrt
链接。
您需要将rt
添加到您的target_link_libraries
。
您应该直接检查从dlsym()
返回的值是否有错误。 根据dlsym
手册页:
返回值
成功时,这些函数返回与符号关联的地址。 失败时返回 NULL; 可以使用 dlerror(3) 诊断错误原因。
此外,您的代码不是线程安全的:
static ShmOpenFuncPtr_t real_shm_open = nullptr;
std::cout << "custom shm_open\n";
if (nullptr == real_shm_open)
{
real_shm_open = reinterpret_cast<ShmOpenFuncPtr_t>(dlsym(RTLD_NEXT, "shm_open"));
char* error = dlerror();
if (error != nullptr)
{
std::cout << "could not load shm_open at runtime! error: " << error << "\n";
return -1;
}
}
两个或多个线程可以并行执行代码,导致损坏的real_shm_open
既不是NULL
也不正确。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.