理解为C创建malloc和free的包装函数

时间:2011-11-29 05:20:26

标签: c

我在Linux上,尝试使用示例Create a wrapper function for malloc and free in C;但似乎我不理解某些东西。

我有一个代表.so文件的.c源代码;和另一个.c源,它是一个测试者(下图)。所以我这样建造:

# the .so
gcc -c -fpic mymalloc.c
gcc -shared -Wl,-soname,libmymalloc.so -o libmymalloc.so mymalloc.o

# the tester
gcc -o malloctest -Wall -g malloctest.c

......最后我像这样测试:

$ LD_PRELOAD=./libmymalloc.so ./malloctest
malloc'ed 5 arrays
free'd 5 arrays

...我只是得到了测试程序的输出 - 而不是每个malloc / free调用的.so打印输出(就像我一样,否则,理解效果应该是)。

任何人都可以帮我解决我的错误吗? 非常感谢提前,
干杯!

mymalloc.c:

//~ gcc -c -fpic mymalloc.c
//~ gcc -shared -Wl,-soname,libmymalloc.so -o libmymalloc.so mymalloc.o
//~ https://svn.apache.org/repos/asf/incubator/triplesoup/donations/TRIPLES-3-RDFStore/dbms/deamon/mymalloc.h
//~ https://stackoverflow.com/questions/262439/create-a-wrapper-function-for-malloc-and-free-in-c

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


void * debug_malloc( size_t len, char * file, int line);
void debug_free( void * addr, char * file, int line );

//~ #define mymalloc(x) debug_malloc(x,__FILE__,__LINE__)
//~ #define myfree(x) debug_free(x,__FILE__,__LINE__)
#define malloc(x) debug_malloc(x,__FILE__,__LINE__)
#define free(x) debug_free(x,__FILE__,__LINE__)


//~ void* malloc(size_t sz)
void * debug_malloc( size_t len, char * file, int line )
{
  void *(*libc_malloc)(size_t) = dlsym(RTLD_NEXT, "malloc");
  //~ printf("malloc\n");
  printf("Malloc from %s:%d",file,line);
  return libc_malloc(len);
}

//~ void free(void *p)
void debug_free( void * addr, char * file, int line )
{
  void (*libc_free)(void*) = dlsym(RTLD_NEXT, "free");
  //~ printf("free\n");
  printf("Free from %s:%d",file,line);
  libc_free(addr);
}

//~ int main()
//~ {
  //~ free(malloc(10));
  //~ return 0;
//~ }

malloctest.c:

// gcc -o malloctest -Wall -g malloctest.c

#include <stdlib.h>
#include <stdio.h>

int main() {
  int *ptr1 = (int *) malloc(10 * sizeof (int));
  int *ptr2 = (int *) malloc(10 * sizeof (int));
  int *ptr3 = (int *) malloc(10 * sizeof (int));
  int *ptr4 = (int *) malloc(10 * sizeof (int));
  int *ptr5 = (int *) malloc(10 * sizeof (int));
  printf("malloc'ed 5 arrays\n");

  free(ptr1);
  free(ptr2);
  free(ptr3);
  free(ptr4);
  free(ptr5);
  printf("free'd 5 arrays\n");

  return 0;
}

3 个答案:

答案 0 :(得分:3)

您实际上已经调用了libc malloc而不是您的实现。尝试用debug_malloc替换malloc或者用debug_free替换,看看区别

答案 1 :(得分:1)

define需要包含在malloctest.c文件中的头文件中,这样就可以调用正确的malloc,free。因为它现在没有任何效果,因为define仅适用于mymalloc。

做标题
#define malloc(x) debug_malloc(x,__FILE__,__LINE__)
#define free(x) debug_free(x,__FILE__,__LINE__)

加上原型并包含在malloctest.c中

答案 2 :(得分:0)

由于OP已经有点密集,我将在此澄清:

我对LD_PRELOAD方法感兴趣,因为我认为可以使用它,没有更改原始可执行文件(对我而言,还包括不将其链接到新的.so)。我试着按照@Abhajit和@Anders K的建议,实际把所有内容放在可执行文件中 - 这将消除.so,但只是为了看看我是否可以让它工作......我不能。

当我尝试在下面构建源代码时,我得到:

/tmp/ccyUrbW8.o: In function `debug_malloc':
/path/to/malloctest.c:13: undefined reference to `dlsym'
/tmp/ccyUrbW8.o: In function `debug_free':
/path/to/malloctest.c:22: undefined reference to `dlsym'
collect2: ld returned 1 exit status

...如果使用dlsym进行构建,则不会出现-fPIC问题,而AFAIK仅适用于.so文件。所以使用dlsym的代码原本打算在.so中使用 - 但是如何编译整个东西,所以它有效吗?

修改后的单个文件malloctest.c:

// gcc -o malloctest -Wall -g malloctest.c

// _GNU_SOURCE => RTLD_NEXT
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

//~ #include "malloctest.h"

void * debug_malloc( size_t len, char * file, int line )
{
  void *(*libc_malloc)(size_t) = dlsym(RTLD_NEXT, "malloc");
  //~ printf("malloc\n");
  printf("Malloc from %s:%d",file,line);
  return libc_malloc(len);
}

//~ void free(void *p)
void debug_free( void * addr, char * file, int line )
{
  void (*libc_free)(void*) = dlsym(RTLD_NEXT, "free");
  //~ printf("free\n");
  printf("Free from %s:%d",file,line);
  libc_free(addr);
}

#define malloc(x) debug_malloc(x,__FILE__,__LINE__)
#define free(x) debug_free(x,__FILE__,__LINE__)



int main() {
  int *ptr1 = (int *) malloc(10 * sizeof (int));
  int *ptr2 = (int *) malloc(10 * sizeof (int));
  int *ptr3 = (int *) malloc(10 * sizeof (int));
  int *ptr4 = (int *) malloc(10 * sizeof (int));
  int *ptr5 = (int *) malloc(10 * sizeof (int));
  printf("malloc'ed 5 arrays\n");

  free(ptr1);
  free(ptr2);
  free(ptr3);
  free(ptr4);
  free(ptr5);
  printf("free'd 5 arrays\n");

  return 0;
}