2

我在通过使用函数插入监视 malloc 和 free 时遇到了一个小问题。

当只为 malloc 执行函数插入时,它按预期工作。但是,当尝试插入 free 时,它​​也会进入一个循环;我似乎免费被递归调用,但我只是不知道为什么。

这是 malloc 和 free 函数的代码。(mod_malloc_free.c)

#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <dlfcn.h>

void* malloc(size_t size) {

   static void* (*real_malloc)(size_t) = NULL;

   printf("%s\n", "inside shared malloc");

   if(!real_malloc)
        real_malloc = dlsym(RTLD_NEXT, "malloc");

   void * p = real_malloc(size);

   printf("malloc(%d) = %p\n",size, p );

   printf("%s\n", "returning from shared malloc");

   return p;

   }

void free(void* ap ) {

    static void (*real_free)(void*) = NULL;

  printf("inside shared free...\n");

  if(!real_free)
       real_free = dlsym(RTLD_NEXT, "free");

   printf("free = %p\n", ap);

   real_free(ap);

}

主要简单地包括:

#include <stdio.h>
#include <malloc.h>

int main(void) {

    void * p = malloc(123);

    printf("p = %p\n",p );

    free(p);

    return 0;

}

编译为:

gcc -shared -ldl -fPIC mod_malloc_free.c -o libcustom.so

gcc -o smallMain -Wall smallMain.c

LD_PRELOAD=./libcustom.so ./smallMain

此致

尼菲肯

4

3 回答 3

1

glibc 提供带有__前缀的真实符号(不弱)。所以尝试查找符号__malloc__free

并且只是为了防止递归,不要使用 printf() 或任何其他可能需要在包装器内分配内存的函数。

于 2013-02-21T10:14:38.250 回答
1

很可能printf是在召唤free。当然,这意味着它还执行内存分配,所以它提出了一个问题,为什么在malloc. 可能printf正在调用替代方案,例如callocor realloc

要仅插入您自己的代码,请使用宏来替换调用或单独链接您的代码,并使用链接器功能在与外部库链接之前删除您的mallocand free(例如-unexported_symbolApple 版本的 ld 的开关)。

要插入所有代码,printf请从您的例程中删除。调用更简单的例程,例如fputs代替。或者,使用静态标志来抑制递归:

void free(void *ap)
{
    static void (*RealFree)(void *) = 0;
    If (!RealFree)
        RealFree = dlsym(RTLD_NEXT, "free");

    static int InsideCall = 0;
    if (!InsideCall)
    {
        InsideCall = 1;
        … Do stuff…
        InsideCall = 0;
    }
}

(如果您有多个线程或执行内存分配的异常处理程序,则必须采取额外的步骤。)

于 2013-02-21T13:39:53.487 回答
0

我建议您使用宏将 malloc/free 替换为您自己的函数,而不是使用函数指针。

这样的事情应该这样做:

 #ifdef REPLACE_MALLOC
 #define malloc(x) my_mallc(x)
 #define free(x)   my_free(x)
 #endif

不要忘记做:

 #undef malloc
 #undef free

在您实际实施之前。

但是请注意,从技术上讲,这不是“正确的”——你不应该将宏用于标准库的一部分,所以如果它停止工作,请不要在这里抱怨——特别是,微软已经做了这样的事情在调试版本中替换malloc为它的调试版本。

于 2013-02-21T10:34:43.850 回答