【问题标题】:Free all memory allocated by LLVM on exit在退出时释放 LLVM 分配的所有内存
【发布时间】:2020-05-09 07:38:18
【问题描述】:

我正在使用 LLVM-C 编写一个小玩具语言。 我也在使用 valgrind 来检查内存泄漏。

这是我的基本婴儿计划:

#include <stdio.h>
#include <llvm-c/Core.h>

int main()
{
    size_t length;
    LLVMModuleRef module = LLVMModuleCreateWithName("llvm.hello");
    printf("Module name: %s\n", LLVMGetModuleIdentifier(module, &length));
    LLVMDisposeModule(module);
    LLVMShutDown();
    return 0;
}

我可以按预期正常编译和运行程序。但是,当我通过 valgrind 运行程序时,它告诉我我有一些像这样“仍然可以访问”的分配内存。

valgrind  --leak-check=full  out/hello_llvm
==5807== LEAK SUMMARY:
==5807==    definitely lost: 0 bytes in 0 blocks
==5807==    indirectly lost: 0 bytes in 0 blocks
==5807==      possibly lost: 0 bytes in 0 blocks
==5807==    still reachable: 56 bytes in 2 blocks
==5807==         suppressed: 0 bytes in 0 blocks

在此站点上搜索答案时,我发现许多编码人员都说“仍然可以访问”内存泄漏并不是什么大问题。我不想为此争论。我想要的是在终止我的程序之前摆脱所有分配的内存。

有什么方法可以在终止前将分配的内存减少到零?

【问题讨论】:

  • 如果在您的main 失去任何访问方式后仍有可访问的分配内存,则必须从静态对象指向它。换句话说,LLVM 有一些具有静态存储持续时间的对象(直接或间接)指向分配的内存。 valgrind 会向你展示更多吗?您可能必须深入研究 LLVM 源代码才能了解它在做什么。在不同的调用中分配一些内存以供长期使用可能是有意义的,但它可以被视为设计缺陷。
  • @EricPostpischil 如果我查看 valgrind 给出的详细报告,似乎已经为线程目的进行了一些分配,但没有释放... ==7288== by 0xA134826: __pthread_once_slow (pthread_once. c:116) ==7288== by 0x580D675: llvm::ManagedStaticBase::RegisterManagedStatic

标签: c memory-leaks llvm valgrind


【解决方案1】:

valgrind不给0的时候也让我很紧张,在这种情况下我会创建一个抑制文件,如果你想试试看:

创建并编译一个最小测试:

> cat demo.c
#include <stdlib.h>

int main(void)
{
    malloc(10); // leak
}

创建抑制文件:

valgrind --leak-check=full --show-reachable=yes --error-limit=no --gen-suppressions=all --log-file=minimal.supp ./demo

编辑生成的minimal.supp 文件,你会看到类似

==3102== Memcheck, a memory error detector
==3102== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3102== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3102== Command: ./demo
==3102== Parent PID: 2633
==3102== 
==3102== 
==3102== HEAP SUMMARY:
==3102==     in use at exit: 10 bytes in 1 blocks
==3102==   total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==3102== 
==3102== 10 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3102==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==3102==    by 0x10915A: main (in /home/david/demo)
==3102== 
{
   <insert_a_suppression_name_here>
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:main
}
==3102== LEAK SUMMARY:
==3102==    definitely lost: 10 bytes in 1 blocks
==3102==    indirectly lost: 0 bytes in 0 blocks
==3102==      possibly lost: 0 bytes in 0 blocks
==3102==    still reachable: 0 bytes in 0 blocks
==3102==         suppressed: 0 bytes in 0 blocks
==3102== 
==3102== For lists of detected and suppressed errors, rerun with: -s
==3102== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

删除所有以== 开头的行并保存如下内容:

{
   <my stupid external LLVM leak>
   Memcheck:Leak
   match-leak-kinds: definite
   fun:malloc
   fun:main
}

现在使用抑制文件运行 valgrind:

valgrind --tool=memcheck --leak-check=full --show-reachable=yes --error-limit=no --suppressions=minimal.supp ./demo

结果是:

==3348== Memcheck, a memory error detector
==3348== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==3348== Using Valgrind-3.15.0 and LibVEX; rerun with -h for copyright info
==3348== Command: ./demo
==3348== 
==3348== 
==3348== HEAP SUMMARY:
==3348==     in use at exit: 10 bytes in 1 blocks
==3348==   total heap usage: 1 allocs, 0 frees, 10 bytes allocated
==3348== 
==3348== LEAK SUMMARY:
==3348==    definitely lost: 0 bytes in 0 blocks
==3348==    indirectly lost: 0 bytes in 0 blocks
==3348==      possibly lost: 0 bytes in 0 blocks
==3348==    still reachable: 0 bytes in 0 blocks
==3348==         suppressed: 10 bytes in 1 blocks
==3348== 
==3348== For lists of detected and suppressed errors, rerun with: -s
==3348== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 1 from 1)

如您所见,泄漏已从“肯定丢失”变为“已抑制”

【讨论】:

  • 我喜欢你的回答,因为它解决了我的部分实际问题。我将能够抑制我无法控制的错误,然后专注于我自己的错误。但是,它并没有给我一种将所有内容减少到零的方法,我的意思是在 LLVM 中释放泄漏的剩余内存。但这可能是不可能的或完全可行的。无论如何,在接受你的答案之前,我会稍等片刻,看看是否有人能提出这个答案。同时,我会在我的项目中轻松应用您详细的解决方案。谢谢;-)
  • 感谢 Frederic,是的,不完全是 0,但至少您可以控制自己的泄漏。
  • 我刚刚应用了您的解决方案,它可以完美运行。再次感谢。
猜你喜欢
  • 2011-08-02
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 2016-11-16
  • 2021-03-15
  • 2018-08-27
  • 1970-01-01
  • 2011-12-09
相关资源
最近更新 更多