簡體   English   中英

dlsym 在動態加載 shm_open 時導致段錯誤

[英]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_openlibrt.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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM