Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Has anyone an example for wrapping a function in C++?

Tags:

c++

linux

gcc

g++

I have searched online a lot but I couldn't find an example that works with g+, all examples work with GCC.

The error I keep getting is:

wrap_malloc.o: In function `__wrap_malloc(unsigned int)':
wrap_malloc.cc:(.text+0x20): undefined reference to `__real_malloc(unsigned int)'
wrap_malloc.o: In function `main':
wrap_malloc.cc:(.text+0x37): undefined reference to `__wrap_malloc'
collect2: ld returned 1 exit status

The code that creates this error is the following (this code works if I compile it with GCC and change the headers from cstdio to stdio.h):

#include <cstdio>
#include <cstdlib>

void *__real_malloc(size_t);

void *__wrap_malloc(size_t c) {
  printf("My malloc called with %d\n", c);
  return __real_malloc(c);
}

int main(void) {
  void *ptr = malloc(12);
  free(ptr);
  return 0;
}

This is how I compile it:

wrap_malloc.o: wrap_malloc.cc
    g++ -c wrap_malloc.cc -o wrap_malloc.o

wrap_malloc: wrap_malloc.o
    g++ wrap_malloc.o -o wrap_malloc -Wl,--wrap,malloc
like image 569
John B. Avatar asked Sep 29 '10 21:09

John B.


1 Answers

When you use a C++ compiler, all names are mangled. What this means becomes clear when you run nm wrap_malloc.o, which should give you something like this:

00000000 b .bss
00000000 d .data
00000000 r .rdata
00000000 t .text
         U __Z13__real_mallocj
00000000 T __Z13__wrap_mallocj
         U _printf

This means that you use (U) a symbol called __Z13__real_mallocj and that you define a symbol in the text segment (T) called __Z13__wrap_mallocj. But you probably want a symbol called __real_malloc. To achieve this you have to say the compiler that __real_malloc is a C-style function, like this:

extern "C" void *__real_malloc(size_t);

extern "C" void *__wrap_malloc(size_t c) {
  printf("My malloc called with %d\n", c);
  return __real_malloc(c);
}

Now the output of nm is:

00000000 b .bss
00000000 d .data
00000000 r .rdata
00000000 t .text
         U ___real_malloc
00000000 T ___wrap_malloc
         U _printf

You can see that the name _printf hasn't changed. This is because in the header files, many functions are declared as extern "C" already.

Note: I did all of the above on Windows in the cygwin environment. That's why there is an additional leading underscore in the external symbols.

like image 90
Roland Illig Avatar answered Sep 27 '22 21:09

Roland Illig