在没有LD_PRELOAD的情况下覆盖libc函数

时间:2016-12-01 16:35:07

标签: c++ linux cmake dynamic-linking

我计划实现自己的malloc / free,在尝试将我的共享库与我的可执行文件链接时遇到了一些问题。

现在,我可以让它与LD_PRELOAD一起使用,但不是通过将.so链接到可执行文件,虽然我可以通过将它们链接到我的可执行文件来获得类似tcmalloc的类似库,并且希望做同样的事。

我使用cmake构建所有内容,这是我的共享库的CMakeLists:

data

这是exports.cpp:

cmake_minimum_required(VERSION 2.8)
project(allocator)

add_library(allocator SHARED exports.cpp)
target_link_libraries(allocator dl)

target_compile_features(allocator PRIVATE cxx_range_for)

正如我所说,尝试将生成的.so链接到可执行文件并不真正链接库(在ldd中没有条目,并且调用了libc malloc)。我想知道我做错了什么。

编辑: 我也试过用

进行编译
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif

#include <stdio.h>
#include <dlfcn.h>

typedef void * (*MallocType)(size_t);
typedef void (*FreeType)(void *);

static bool g_initialized = false;

static MallocType real_malloc = nullptr;
static FreeType   real_free   = nullptr;

static void alloc_init(void)
{
    real_malloc = (MallocType) dlsym(RTLD_NEXT, "malloc");

    if (!real_malloc)
    {
        fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
    }

    real_free = (FreeType) dlsym(RTLD_NEXT, "free");

    if (!real_free)
    {
        fprintf(stderr, "Error in `dlsym`: %s\n", dlerror());
    }

    g_initialized = true;
}

extern "C" void * malloc(size_t size)
{
    if (!g_initialized)
    {
        alloc_init();
    }

    printf("Allocate %u.\n", size);
    return real_malloc(size);
}

extern "C" void free(void *ptr)
{
    if (!g_initialized)
    {
        alloc_init();
    }

    printf("Free %p.\n", ptr);
    real_free(ptr);
}

1 个答案:

答案 0 :(得分:2)

CMake不是您选择的工具。 CMake为C源创建了makefile或IDE项目文件,并且有一种工作假设,即所有代码都以传统方式执行常规操作。如果你已经承诺提供自己的malloc,那就不再适用了。

大多数C编译器可以被哄骗链接用户提供的malloc版本,通常是通过播放链接标志的顺序。但这是一个容易出错的过程,因为可能会有间接调用或子模块提前绑定。您可以通过重命名malloc()mymalloc()立即解决所有这些问题,但当然您必须重写客户端代码。