もともとgccにはmallocをhookするAPIがあったんだが、アレは今やdeprecatedらしいぜ。 じゃあどうすればいいかというと「自分でmalloc/free書け」ということらしいが、ちょっと手を加えたいだけのときに全部書くなんてやってられない。
malloc/freeを定義して、ダイナミックにロードした普通のmalloc/freeを呼び出すという方法がある。
dlopenやdlsymもmallocを使うから要注意だぜ。 ここに書いた実装は、ダイナミックローディングが完了する前にmallocが呼ばれたらstaticに確保したメモリから切り出して返してる。
ウェブで検索しても見当たらなくて、割と悩んでこのやり方にたどり着いたんだが、今検索したら同じことやってるページが複数ある。収斂進化ってヤツか。
#include <stdlib.h>
#include <dlfcn.h>
static void * (* ext_malloc)(size_t) = NULL;
static void (* ext_free)(void *) = NULL;
static int offset = 0;
static char buffer[256];
void * malloc(size_t size)
{
if (ext_malloc && ext_free)
{
return ext_malloc(size);
}
void * ptr = & buffer[offset];
offset += size;
if (sizeof(buffer) < offset)
{
// make the buffer bigger when this happens.
exit(2);
}
return ptr;
}
void free(void * ptr)
{
if (buffer <= (char *) ptr && (char *) ptr < buffer + sizeof(buffer))
{
ext_free(ptr);
}
}
int main(int argc, char * * argv)
{
void * libc = dlopen("libc.so.6", RTLD_LAZY);
if (! libc)
{
exit(1);
}
ext_malloc = (void * (*)(size_t)) dlsym(libc, "malloc");
ext_free = (void (*)(void *)) dlsym(libc, "free");
// do whatever you want!
ext_malloc = NULL;
ext_free = NULL;
dlclose(libc);
return 0;
}