2011-04-28 80 views
6

我写了一个自定义库,它使用标准的C原型实现了malloc/calloc/realloc/free,并且我想出了如何将它编译为so。我想通过链接一个标准的应用程序来测试这个库吗?什么是这样做的好方法?一旦我有一个工作库,我假设我可以用LD_PRELOAD加载它,但是如何让我的函数与系统库共存,但优先于系统库?我的函数需要调用malloc以获得内存运行,所以我不能完全抛弃stdlib ...帮助?编译一个自定义的malloc

+1

我相当肯定我的答案在于使用动态链接器。 – conartist6 2011-04-28 17:43:06

回答

4

您试图替换的函数是标准的C函数,而不是宏,而不是系统调用。所以你必须简单地给你的函数使用相同的名字并将它们编译到共享库中。

然后,使用LD_PRELOAD在二进制启动之前预先加载您的库。由于所有地址都解析了一次,链接器会找出你函数的地址并记住它们的名字,以后不会在标准库中查找它们。

如果您的程序与标准运行时间静态链接,则此方法可能不起作用。此外,它不适用于Mac OS X,因为还有另一个插值API。

在Linux中,例如,为了让您的功能并存的(也就是说,如果你想在自己实现malloc使用的系统malloc),你必须打开使用dlopen手动标准库,查找功能你需要在那里使用dlsym,然后通过地址给他们打电话。

+0

我以为我会碰到更多的问题,但我删除了包含标准库和加载malloc后退出与dlsym一切编译好。谢谢! – conartist6 2011-04-28 18:03:09

+0

@ conartist6:不客气:) – 2011-04-28 18:04:25

1

如果你有使用这个库的源代码的控制权,这里有一种可能性。使用不同的函数名称:例如,而不是malloc,将其称为newCoolMalloc。此方法有时更简单,不依赖于特殊的链接器选项。

然后在您的代码中,使用#define使代码调用所需的一组函数。你可以#定义malloc是不同的。例如:

#define malloc newCoolMalloc 
#define free newCoolFree 

如果你这样做,但你必须非常小心地包括这一贯。否则,你会冒着在一个地方使用stdlib malloc的风险,然后在另一个地方使用自由空间,这导致了一些麻烦的bug。一种有助于缓解这种情况的方法是(如果可能)在您自己的代码中使用分配和自由函数的自定义名称。然后更容易确保正确的被调用。您可以为各自的malloc函数或甚至原始的stdlib malloc函数定义各种自定义名称。

例如,您可能会在代码中使用mallocPlaceHolder的实际名称:

someThing = mallocPlaceHolder(nbytes); 

然后你定义一下会更是这样的:

#define mallocPlaceHolder myCoolMalloc 

如果没有形式mallocPlaceHolder的功能(和相关的免费)实际存在,它避免了混合不同的库。

+0

不幸的是,这并不适合我。我想通过使用这个库运行别人的应用程序来测试我的分配器。我可以在理论上重新编译这些内容,但时间和精力将通过LD_PRELOAD保存。 – conartist6 2011-04-28 18:04:39

2

不要根据malloc()编写malloc() - 使用sbrk编写它,它可以直接从操作系统获取内存。

+0

有趣的建议。我会研究它。 – conartist6 2011-04-28 18:03:20

+0

在某些系统上,'sbrk()'不再可用。例如,在我目前的Mac OS X上,该名男子说:“brk和sbrk函数是虚拟内存管理出现之前早期遗留下来的历史好奇。”如果你看看函数的全部来源,它甚至可以有趣的:'errno = ENOMEM; return((void *) - 1);' – achedeuzot 2015-01-20 18:02:26