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

时间:2022-09-06 21:28:20

I'm planning to implement my own malloc/free and I ran into some problems while trying to link my shared library with my executable.

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

Right now, I can get it to work with LD_PRELOAD, but not by linking the .so to the executable, although I can get similiar libraries, like tcmalloc, to work properly just by linking them to my executable, and would like to do the same.

现在,我可以使用LD_PRELOAD,但不能将.so链接到可执行文件,尽管我可以通过将它们链接到我的可执行文件来获得类似tcmalloc的类似库,并且想要执行相同。

I'm building everything with cmake, this is the CMakeLists of my shared library:

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

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)

and this is exports.cpp:

这是exports.cpp:

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

As I said, trying to link the resulting .so to an executable doesn't really link the library (there's no entry in ldd, and libc malloc is called). I was wondering what am I doing wrong.

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

Edit: I've also tried compiling with

编辑:我也尝试过编译

g++ -o liballocator.so -shared exports.cpp -std=c++11 -fPIC -ldl
g++ -o test launcher.cpp memusage.cpp app.cpp -ldl -L. -lallocator -std=c++11

1 个解决方案

#1


1  

CMake isn't your tool of choice here. CMake creates makefiles or IDE project files for C source, and has a kind of working assumption that all the code is doing conventional things in conventional ways. That is no longer true if you have undertaken to provide your own malloc.

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

Most C compilers can be coaxed into linking a user-supplied version of malloc, often by playing about with the order of the link flags. But it is an error-prone process, since there might be indirect calls or submodules bound early. You can instantly solve all those problems by renaming malloc() mymalloc(), but then of course you must rewrite the client code.

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

#1


1  

CMake isn't your tool of choice here. CMake creates makefiles or IDE project files for C source, and has a kind of working assumption that all the code is doing conventional things in conventional ways. That is no longer true if you have undertaken to provide your own malloc.

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

Most C compilers can be coaxed into linking a user-supplied version of malloc, often by playing about with the order of the link flags. But it is an error-prone process, since there might be indirect calls or submodules bound early. You can instantly solve all those problems by renaming malloc() mymalloc(), but then of course you must rewrite the client code.

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