Reputation: 343
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.
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.
I'm building everything with cmake, this is the CMakeLists of my shared library:
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:
#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.
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
Upvotes: 5
Views: 1491
Reputation: 6404
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.
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.
Upvotes: 2