7

我有很多可能从 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)
4

3 回答 3

12

Valgrind 源代码 3.6.1 版中包含的常见问题解答确实详细说明了一点:

“可能丢失”意味着您的程序正在泄漏内存,除非您正在使用可能导致它们指向已分配块中间的指针做不寻常的事情;请参阅用户手册了解一些可能的原因。如果您不想看到这些报告,请使用 --show-possibly-lost=no。

(5.2. 杂项,Valgrind 常见问题解答)

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

于 2011-07-24T08:18:25.087 回答
5

来自Valgrind faq:“可能丢失”意味着您的程序正在泄漏内存,除非您使用指针做有趣的事情。这有时是合理的。如果您不想看到这些报告,请使用 --show-possibly-lost=no。

于 2011-07-21T05:28:33.537 回答
5

在将 SQLite 与 Valgrind 一起使用后,我也有同样的好奇心,并发现了这个错误条目,这表明在 SQLite 的情况下,这是一个误报。看起来 SQLite 确实使用了导致 Valgrind 响应的内部指针。

“错误 573688 有新信息——这些都是“可能的泄漏”和误报,因为 SQLite 将其指针移动到从块开始的 8 个字节的堆块中。修复的最简单方法是扩展 Valgrind 以抑制“可能的泄漏” " 具体报告;目前您只能抑制所有泄漏,这将是危险的,因为任何 SQLite 泄漏都永远不会被捕获。(虽然我认为这可能是同时一个合理的步骤。)"

错误 639408 - 抑制 Valgrind 运行中的 sqlite 泄漏

于 2012-02-19T00:26:45.200 回答