在退出时释放LLVM分配的所有内存。

3

我正在使用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运行程序时,它告诉我有一些"still reachable"(仍可访问)的分配内存,就像这样。

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

在这个网站上搜索答案时,我发现许多程序员说“仍然可达”的内存泄漏并不是什么大问题。我不想争论这个问题。我想做的是在终止程序之前清除所有分配的内存。
有没有办法在终止程序之前将分配的内存减少到零?

1
如果在您的main失去访问已分配内存的任何方法后仍然存在可达内存,则必须从静态对象指向它。换句话说,LLVM具有一些具有静态存储期的对象(直接或间接)指向分配的内存。valgrind会显示更多吗?您可能需要深入了解LLVM源代码以查看它在做什么。为长期在不同调用之间使用一些内存进行分配可能是有道理的,但这可能被视为设计缺陷。 - Eric Postpischil
@EricPostpischil 如果我查看valgrind给出的详细报告,似乎已经为线程目的进行了一些分配,但没有释放...==7288== 由0xA134826引起:__pthread_once_slow(pthread_once.c:116) ==7288== 由0x580D675引起:llvm :: ManagedStaticBase :: RegisterManagedStatic - Frederic
1个回答

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)

正如您所看到的,泄漏已从“确定丢失”移动到“抑制”。

1
我喜欢你的回答,因为它解决了我实际问题的一部分。我将能够抑制我无法控制的错误,并集中精力处理我的问题。虽然它不能彻底减少所有问题,比如释放LLVM中泄漏的残留内存。但也许这是不可能或难以实现的。在接受您的答案之前,我会等待一段时间看看是否有人能提出这个答案。同时,我会立即将您详细解决方案应用到我的项目中。谢谢;-) - Frederic
1
谢谢Frederic,是的,虽然不是完全没有泄漏,但至少你可以控制自己的泄漏。 - David Ranieri
1
我刚刚应用了你的解决方案,它完美无缺地运行了。再次感谢。 - Frederic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接