Problemas com interposição LD_PRELOAD e calloc () para determinados executáveis

Relacionando a um @ anteri pergunta minha

Interrompi com sucessomalloc, mascalloc parece ser mais problemático.

Isso ocorre com determinados hosts,calloc fica preso em um loop infinito com um possível @ intercalloc ligue para dentrodlsym. No entanto, um host de teste básico não exibe esse comportamento, mas o comando "ls" do meu sistema exib

Aqui está o meu código:

// build with: g++ -O2 -Wall -fPIC -ldl -o libnano.so -shared Main.cc
#include <stdio.h>
#include <dlfcn.h>

bool gNanoUp = false;// global

// Function types
typedef void* (*MallocFn)(size_t size);
typedef void* (*CallocFn)(size_t elements, size_t size);

struct MemoryFunctions {
    MallocFn   mMalloc;
    CallocFn   mCalloc;
};

MemoryFunctions orgMemFuncs;

// Save original methods.
void __attribute__((constructor)) __nano_init(void) {
    fprintf(stderr, "NANO: init()\n");

    // Get address of original functions
    orgMemFuncs.mMalloc = (MallocFn)dlsym(RTLD_NEXT, "malloc");
    orgMemFuncs.mCalloc = (CallocFn)dlsym(RTLD_NEXT, "calloc");

    fprintf(stderr, "NANO: malloc() found @%p\n", orgMemFuncs.mMalloc);
    fprintf(stderr, "NANO: calloc() found @%p\n", orgMemFuncs.mCalloc);

    gNanoUp = true;
}

// replacement functions
extern "C" {
    void *malloc(size_t size) {
        if (!gNanoUp) __nano_init();
        return orgMemFuncs.mMalloc(size);
    }

    void* calloc(size_t elements, size_t size) {
        if (!gNanoUp) __nano_init();
        return orgMemFuncs.mCalloc(elements, size);
    }
}

gora, quando faço o seguinte, recebo um loop infinito seguido por uma falha seg, por exemplo:

% setenv LD_PRELOAD "./libnano.so"
% ls
...
NANO: init()
NANO: init()
NANO: init()
Segmentation fault (core dumped)

No entanto, se eu comentar ocalloc interposer, quase parece trabalhar

% setenv LD_PRELOAD "./libnano.so"
% ls
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
<directory contents>
...

Então algumas coisas com "ls" que significainit() é chamado duas vezes.

EDIT Observe que o seguinte programa host funciona corretamente -init() é chamado apenas uma vez ecalloc é interposto com sucesso, como você pode ver na saíd

// build with: g++ test.cc -o test
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {

    void* p = malloc(123);
    printf("HOST p=%p\n", p);
    free(p);

    char* c = new char;
    printf("HOST c=%p\n", c);
    delete c;

    void* ca = calloc(10,10);
    printf("HOST ca=%p\n", ca);
    free(ca);
}

% setenv LD_PRELOAD "./libnano.so"
% ./test 
NANO: init()
NANO: malloc() found @0x3b36274dc0
NANO: calloc() found @0x3b362749e0
HOST p=0x601010
HOST c=0x601010
HOST ca=0x601030