用LD_PRELOAD和C++中的全局作用域对象加载堆分析器

Loading a heap analyser with LD_PRELOAD, and global scope objects in C++

本文关键字:作用域 全局 对象 加载 分析器 LD PRELOAD C++      更新时间:2023-10-16

我们编写了一个堆分析器(供参考,称为lib_debug),它覆盖freemalloc(以及其他),主要用于监视我们的应用程序中的错误,如内存泄漏,这些应用程序部署在运行Linux的PPC系统上。lib_debug被编译为共享库,并在需要时加载LD_PRELOAD

到目前为止,这个调试器运行得很好;每当调用malloc时,都会在堆栈上创建一个内存监视器singleton,当这个singleton在退出时超出范围时,它会报告任何未释放的内存。

但是,我们的一个应用程序现在在全局范围内分配一个std::vector。这个全局vector似乎是在我们的堆分析器创建之前创建的,最重要的是在之后销毁。因此,一旦在main中,如果我们在vector中插入任何内容,lib_debug就会认为我们在关闭时存在内存泄漏。

举例来说,这就是我认为的事件序列:

  1. CCD_ 12从CCD_
  2. CCD_ 14是在全局范围的堆栈上创建的
  3. lib_debug初始化发生-malloc在某个地方被调用,这导致在堆栈上创建实际的堆分析器单例
  4. 输入main
  5. 发生std::vector::push_back(),在堆上分配内存
  6. CCD_ 19退出
  7. lib_debug堆分析器singleton超出范围,它发现vector没有释放内存-报告错误
  8. vector超出全局范围,释放内存
  9. 程序终止

因此,有没有什么方法可以保证我们的LD_PRELOADed单例总是最后一个被删除的东西,从而捕获应用程序中发生的每一个free

如果使用GCC作为编译器,则此操作有效。您可以在库中定义一个函数作为constructor,以便在加载库时执行代码。

static int initialize_lib_debug () __attribute__((constructor));
static int initialize_lib_debug () {
    /* ... */
}