简体   繁体   English

dlsym 在动态加载 shm_open 时导致段错误

[英]dlsym causing segfault when dynamically loading shm_open

I am trying to figure out to load the function shm_open dynamically at runtime and have hit a wall.我试图找出在运行时动态加载 function shm_open并遇到了困难。

My current code is as such:我当前的代码是这样的:

CMakeLists.txt 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 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);
}

}

main.cpp主.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;
}

At the moment, because I give the executable the custom_mann.cpp source file, the linker finds my definition of shm_open before the standard library definition and calls that instead.目前,因为我为可执行文件提供了custom_mann.cpp源文件,所以 linker 在标准库定义之前找到了我对shm_open的定义并改为调用它。 My intention is then to do some logic before calling the real shm_open function.我的意图是在调用真正的shm_open function 之前做一些逻辑。

However, the call to dlsym is returning a null pointer so when real_shm_open is called, a segfault occurs.但是,对dlsym的调用返回一个 null 指针,因此当调用real_shm_open时,会发生段错误。 Strangely, dlerror does not set the error code so the function doesn't return early as I would expect if dlsym is not returning the proper pointer.奇怪的是, dlerror没有设置错误代码,所以如果dlsym没有返回正确的指针,function 不会像我预期的那样提前返回。

Any ideas why this could be happening is much appreciated?非常感谢为什么会发生这种情况的任何想法?

shm_open is supplied by librt.so . shm_openlibrt.so提供。 Per the Linux shm_open() man page (bolding mine):根据Linux shm_open()手册页(加粗我的):

NAME名称

shm_open, shm_unlink - create/open or unlink POSIX shared memory objects shm_open, shm_unlink - 创建/打开或取消链接 POSIX 共享的 memory 个对象

SYNOPSIS概要

 #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);

Link with -lrt .-lrt链接。

You need to add rt to your target_link_libraries .您需要将rt添加到您的target_link_libraries

You should be checking the value returned from dlsym() directly for errors.您应该直接检查从dlsym()返回的值是否有错误。 Per the dlsym man page :根据dlsym手册页

RETURN VALUE返回值

On success, these functions return the address associated with symbol.成功时,这些函数返回与符号关联的地址。 On failure, they return NULL;失败时返回 NULL; the cause of the error can be diagnosed using dlerror(3).可以使用 dlerror(3) 诊断错误原因。

Additionally, your code is not thread-safe:此外,您的代码不是线程安全的:

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;
    }
}

Two or more threads can be executing the code in parallel, resulting in a corrupted real_shm_open that is neither NULL nor correct.两个或多个线程可以并行执行代码,导致损坏的real_shm_open既不是NULL也不正确。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM