3

In file gperftools-2.2.1/src/gperftools/malloc_extension.h, it reads:

// Extra extensions exported by some malloc implementations.  These
// extensions are accessed through a virtual base class so an
// application can link against a malloc that does not implement these
// extensions, and it will get default versions that do nothing.
//
// NOTE FOR C USERS: If you wish to use this functionality from within
// a C program, see malloc_extension_c.h.

My question is how exactly can I access these extensions through a virtual base class?

Usually to load a class from a dynamic library, I would need to write a base class which allows me to get an instance of the wanted class and its functions through polymorphism, as described here.

However to do so there must be some class factory functions available in the API, but there are no such functions in any tcmalloc files. Moreover I would also need to load the tcmalloc library with dlopen(), which is not recommended according to the install note:

...loading a malloc-replacement library via dlopen is asking for trouble in any case: some data will be allocated with one malloc, some with another.

So clearly accessing the extensions through the typical way as mentioned above is not an option. I can get away with using the C versions as declared in malloc_extensions_c.h but just wonder if there is any better solution.

Community
  • 1
  • 1
ptrgreen
  • 103
  • 1
  • 7

2 Answers2

0

I managed to load the malloc extensions via some 'hack', which is not as clean as I would prefer, but it gets the job done. Here is the (temporary) solution for those who are interested in.

First, most of these malloc extension functions are similar to static functions in a way that they are mostly called on the current instance only, e.g. to call the GetMemoryReleaseRate() function on the current process you just call MallocExtension::instance()->GetMemoryReleaseRate(). Therefore we don't need to create a base class and get an instance of MallocExtension class to call these functions.

For the example above, I'd just create a standalone function getMemoryReleaseRate() which simply calls the required function when it gets called, as below:

getMemoryReleaseRate()
{
    MallocExtension::instance()->GetMemoryReleaseRate();
}

This function can be inserted directly to a source file, e.g. tcmalloc.cc, or, if you prefer not to edit the tcmalloc source every time there is a new version, added to your makefile, to be attached to the source file when it is compiled.

Now in your code, you can call the MallocExtension function via the 'facade' function you have created via dlsym(), e.g. as below:

typedef void (*getMemoryReleaseRate)(); 
((getMemoryReleaseRate)dlsym(RTLD_DEFAULT, "getMemoryReleaseRate"))();
ptrgreen
  • 103
  • 1
  • 7
0

Simply including this header and doing MallocExtension::instance()->GetMemoryReleaseRate(); would work too. No need to modify tcmalloc for that.