sdaau
sdaau

Reputation: 38619

Understanding Create a wrapper function for malloc and free in C

I'm on Linux, and trying to work with the examples Create a wrapper function for malloc and free in C; but it seems I'm not understanding something.

I have one .c source representing the .so file; and another .c source which is a tester (below). So I build like so:

# 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

... and finally I test like so:

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

... and I just get the test program output - not printouts from the .so on each malloc/free call (as I, otherwise, understood the effect should be).

Can anyone help me on where am I going wrong? Many thanks in advance,
Cheers!

 

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

Upvotes: 1

Views: 1660

Answers (3)

sdaau
sdaau

Reputation: 38619

As the OP is already kinda dense, I'll put a clarification here:

I was interested in the LD_PRELOAD method, because I thought it would be possible to use it, without changing the original executable (which for me also includes not linking it to a new .so). I tried to follow @Abhajit and @Anders K's advice, and actually put everything in the executable file - which would eliminate the .so, but just to see if I can get it to work... and I can't.

When I try to build the source below, I get:

/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

... and the dlsym problem does not occur if you build with -fPIC, which AFAIK is only for .so files. So that code that uses dlsym must have been originally intended to be used inside an .so -- but how does one compile the whole thing, so it works?

 

modified, single file 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;
}

Upvotes: 0

AndersK
AndersK

Reputation: 36082

The define needs to be in a header file which you include in your malloctest.c file, that way the right malloc,free will be called. As it is now there is no effect since the define only works in mymalloc.

Just do a header with

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

plus prototypes and include in malloctest.c

Upvotes: 1

Abhijit
Abhijit

Reputation: 63737

You have actually invoked libc malloc instead of your implementation. Try replacing malloc with debug_malloc or free with debug_free and see the difference

Upvotes: 3

Related Questions