在Valgrind中,“possible lost”是什么意思?

8

我有很多可能是从valgrind中丢失的条目。这是什么意思? 因为我正在使用sqlite并且它经过了充分的测试,所以我不认为这些是正确的条目。我做错了什么?

 16 bytes in 1 blocks are possibly lost in loss record 30 of 844
    ==23027==    at 0x4A05E1C: malloc (vg_replace_malloc.c:195)
    ==23027==    by 0x6525BE: sqlite3MemMalloc (in app_mem.out)
    ==23027==    by 0x63C579: mallocWithAlarm (in app_mem.out)
    ==23027==    by 0x63C904: sqlite3DbMallocRaw (in app_mem.out)
    ==23027==    by 0x6886D6: codeOneLoopStart (in app_mem.out)
    ==23027==    by 0x68A9C8: sqlite3WhereBegin (in app_mem.out)
    ==23027==    by 0x68CC9E: sqlite3Select (in app_mem.out)
    ==23027==    by 0x6A8644: yy_reduce (in app_mem.out)
    ==23027==    by 0x6AAEAC: sqlite3Parser (in app_mem.out)
    ==23027==    by 0x6AB357: sqlite3RunParser (in app_mem.out)
    ==23027==    by 0x6ADF84: sqlite3Prepare (in app_mem.out)
    ==23027==    by 0x6AE82B: sqlite3LockAndPrepare (in app_mem.out)

在这个链接中清楚地解释了它--https://dev59.com/6nA65IYBdhLWcg3w-jum - Prashanth Peddabbu
3个回答

13

Valgrind版本3.6.1附带的FAQ有更详细的说明:

"possibly lost"意味着你的程序存在内存泄漏,除非你在使用指针时做了一些不寻常的事情,比如让它们指向分配块的中间位置;可以查看用户手册了解可能的原因。如果不想看到这些报告,请使用--show-possibly-lost=no。

(5.2.其他问题, Valgrind FAQ)

Valgrind用户手册介绍了如何跟踪malloc/new分配的所有堆块,并描述了两种跟踪内存的方法:

  1. 通过维护指向内存块开头的"起始指针"
  2. 通过维护指向内存块中间某个位置的"内部指针"

下面是出现内部指针的三种情况:

  1. 该指针最初可能是一个起始指针,并且可能已经被程序故意(或无意)移动了。
  2. 它可能是内存中的随机垃圾值,与内存块完全无关,只是巧合。
  3. 它可能是指向使用new[]分配的C++对象数组(具有析构函数)的指针。

可能的场景:

     Pointer chain            AAA Category    BBB Category
     -------------            ------------    ------------
(5)  RRR ------?-----> BBB                    (y)DR, (n)DL
(6)  RRR ---> AAA -?-> BBB    DR              (y)IR, (n)DL
(7)  RRR -?-> AAA ---> BBB    (y)DR, (n)DL    (y)IR, (n)IL
(8)  RRR -?-> AAA -?-> BBB    (y)DR, (n)DL    (y,y)IR, (n,y)IL, (_,n)DL

Pointer chain legend:
- RRR: a root set node or DR block
- AAA, BBB: heap blocks
- --->: a start-pointer
- -?->: an interior-pointer

Category legend:
- DR: Directly reachable
- IR: Indirectly reachable
- DL: Directly lost
- IL: Indirectly lost
- (y)XY: it's XY if the interior-pointer is a real pointer
- (n)XY: it's XY if the interior-pointer is not a real pointer
- (_)XY: it's XY in either case

(4.2.7 内存泄漏检测,Valgrind 用户手册)

事实证明,“可能丢失”的警告涵盖了上面第5-8块(对于BBB)。

这意味着已经找到了一个或多个指向该块的指针链,但至少其中一个指针是内部指针。 这可能只是在内存中随机出现指向块的值,因此除非您知道自己有内部指针,否则不应将此视为正常情况。

(4.2.7 内存泄漏检测,Valgrind 用户手册)

所以,通过相当啰嗦的方式,我们得出了与fbafelipe相同的结论,即:假设您正在正确使用API,则SQLite可能会泄漏一些内存,或者执行上述有效用例之一。 鉴于SQLite项目的成熟度,可以安全地假设该警告并不是什么大问题。

如果您提供有关如何使用API(以及发生泄漏的情况)的更多信息,其他人可能能够提供更多见解。

参考:Valgrind 3.6.1 源代码,doc/faq.html,doc/mc-manual.html


6
我在使用Valgrind与SQLite后也有同样的好奇心,看到了这个bug报告,表明在SQLite的情况下,这是一个误报。看起来,SQLite确实使用内部指针,这导致Valgrind做出回应。
“Bug 573688有新的信息--这些都是“可能的泄漏”和误报,因为SQLite将其指针移动到从块开始的8字节处。 最简单的解决方法是扩展Valgrind以专门禁止“可能泄漏”的报告;目前只能禁止所有泄漏,这将是危险的,因为任何SQLite泄漏都将无法捕获。(尽管我认为这在此期间可能是合理的步骤)。” Bug 639408 - 抑制Valgrind 运行中的SQLite泄漏

5

来自Valgrind faq: "possibly lost" 意味着您的程序正在泄漏内存,除非您在使用指针时进行了有趣的操作。这有时是可以接受的。如果您不想看到这些报告,请使用 --show-possibly-lost=no。


那么我们应该关心可能丢失的内容吗? - Vivek Goel
是的,如果您在指针上没有做有趣的事情,那么这意味着您的程序存在泄漏。如果您在指针上做有趣的事情,至少检查一下是否有问题是个好主意。 - fbafelipe
啊哈,"work funny things" 是什么意思?我正在使用 SQLite 库,在调用它时只显示这些消息。 - Vivek Goel
1
常见问题集没有说明“有趣的事情”是什么意思,但我认为当你做它时,你会知道它是什么。我建议这样做:检查泄漏堆栈中您实际调用的SQLite函数,然后检查文档以确定在完成后是否应调用另一个释放内存的函数。如果您正在正确使用SQLite API,这意味着要么SQLite正在执行某些与指针有关的操作,这会使valgrind感到困惑,要么您发现了SQLite中的内存泄漏。 - fbafelipe

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