【问题标题】:What does possible lost means in valgrindvalgrind中可能丢失的意思是什么
【发布时间】:2011-10-09 22:33:39
【问题描述】:

我有很多可能丢失的来自 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)

【问题讨论】:

标签: valgrind memcheck


【解决方案1】:

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

【讨论】:

  • 那么我们是否应该关心是否可能丢失?
  • 是的,如果你没有用指针做有趣的事情,这意味着你的程序正在泄漏。如果你用指针做有趣的事情,至少检查一下是否有问题是个好主意。
  • 啊哈工作有趣的事情是什么意思?我正在使用 sqlite 库。只有在它的通话中才会显示这些消息。
  • 常见问题解答并没有说明“有趣的事情”是什么意思,但我相信当你这样做时你就会知道。我建议这样做:检查您实际调用的 sqlite 函数的泄漏堆栈,然后检查文档是否应该在完成后调用另一个函数来释放内存。如果您正确使用 sqlite API,则意味着 sqlite 正在使用使 valgrind 混淆的指针进行某些操作,或者您在 sqlite 中发现了内存泄漏。
【解决方案2】:

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 source, doc/faq.html, doc/mc-manual.html

【讨论】:

    【解决方案3】:

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

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

    Bug 639408 - Suppress sqlite leaks in Valgrind runs

    【讨论】:

      猜你喜欢
      • 2020-11-22
      • 2011-12-18
      • 2011-04-05
      • 2012-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多