c - 如何从动态库中检测主要可执行文件的函数定义 - 特别是 malloc

标签 c linux gcc

因此 libgcc 将使用应用程序的 malloc 和 free(如果它已定义的话)以满足应用程序在某些库调用(例如 realpath)之后调用 free() 的需要。

在我的动态库中,我真的不想使用那个应用程序 malloc/free,因为我通常不信任它 - 我很乐意使用 libgcc 的 malloc 实现,这是大多数应用程序使用的,所以我声明了我自己的 malloc() 函数,该函数通过 dlsym() 调用 libgcc 的实现。

一切都很顺利,直到...我想调用 realpath(也许还有其他人)!作为一个简单的修复,我需要一种方法来执行与 dlsym() 等效的操作,但要在主要可执行文件(我不拥有)上执行此操作以获取应用程序的免费实现(如果有的话)。这样的事情存在吗?

我知道它必须这样做,因为动态链接器“做正确的事”,但普通程序员是否可以访问它,如何访问?

在 realpath 的特殊情况下,我知道我可以提供一个缓冲区,但这会带来缓冲区大小方面的未知危险。对于其他一些调用,我不能这样做。

我也可以使用 objcopy 沿着蜿蜒的符号重命名路径走下去,但如果可能的话,我不想这样做。

[后来]
我确实同意你关于 malloc 可能由另一个动态库定义的观点,我想使用那个版本,而应用程序仍然使用它的编译版本(我已经看到它确实继续使用它,即使 tcmalloc 是预加载的,例如。

我想这会扩展问题以询问是否有任何库定义了 malloc,如果应用程序定义了 malloc,我想挑选我在代码中的每个地方使用哪个版本的 malloc/free 来匹配行为必要时使用 libgcc,不需要时使用,所以我希望能够获得对它们的引用。

在短期内,在调用 libgcc 实现之前,我通过将代码中的 realpath() 替换为使用我的 malloc 预定义缓冲区的版本来解决我当前的问题,但我觉得这非常困难 -助手。

最佳答案

插入的malloc 可以来自任何地方,而不仅仅是可执行文件。它可以是另一个对象的动态部分中的 DT_NEEDED 条目引用的共享对象,或者是使用 LD_PRELOAD 注入(inject)过程镜像的库。

一般来说,许多库都有分配一些东西的函数,然后必须使用 free 释放这些东西。移植到 Windows 的软件不会这样做(因为 DLL 在那里有单独的堆),但除此之外,它并不少见。不仅有 realpath,还有 strdupasprintf,可能还有一些我不记得的其他函数。

在您的情况下,您应该只对此类指针调用 free,并为您自己的内存释放函数使用不同的名称。一旦 malloc 被插入,就不可能安全地使用原始的 libc 分配器,因为它没有被正确初始化。例如,如果您在使用不同的插入式 malloc 的进程中调用 glibc malloc 函数,则 malloc 将不是线程安全的:初始化不是线程安全的,因为实现知道 pthread_create 将在创建第一个新线程之前调用 malloc,从而初始化 malloc,同时进程是单线程的。这就是初始化代码中没有同步的原因。

(libgcc 不提供 malloc,顺便说一句。它来自 libc/glibc。)

关于c - 如何从动态库中检测主要可执行文件的函数定义 - 特别是 malloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49180943/

相关文章:

linux - Linux 内核模块中的 module_init 和 init_module 有什么区别?

c++ - 手动对象构造函数调用

c - 如何知道链接到二进制可执行文件的调试符号文件的名称和/或路径?

c - 浮点值的格式说明符 — 点计数吗?

linux - 创建一个虚假的现实 : Testing Using Virtual Block Devices

c - MicroFocus cobol 命令 cobinit、cobcall 和 cobtidy 在我的 C 程序中抛出错误

c++ - STL 和发布/调试库一团糟

c - 用户在 scanf 中键入空终止符

windows中的c线程HWND错误

linux - 比较两个文件夹时如何避免.git文件