Lazarus中的内存泄漏,如何使用Heaptrcon调试它们?

时间:2013-09-04 12:51:31

标签: delphi memory-leaks freepascal lazarus

在Delphi XE中,我总是使用ReportMemoryLeaksOnShutDown来检测退出我的应用程序时的任何泄漏,大多数我的项目都很小,并且发现泄漏通常并不太困难。

在Lazarus中没有这样的选择,但我刚刚找到了一个名为Heaptrcon的选项,有关此页面的更多信息:http://wiki.lazarus.freepascal.org/Profiling

在项目选项>链接我设置了(-gh)标志,现在我对任何泄漏的恐惧已成为现实。我会发布代码,但因为有很多不同的类和单元我不知道从哪里开始修复这些泄漏,这是一个比我工作过的任何其他项目都要大的项目。

这是一些漏洞的截图:

enter image description here

我的调试技巧几乎为零,到目前为止,我已经查看了我创建的每个对象或类,然后检查它是否已被释放。因为我正在使用很多TLists和Pointers / Objects等,所以我猜想泄漏可能来自任何地方。

是否有任何线索或提示甚至可以从哪里开始寻找?我正在查看大小为16的每个块的调用堆栈,其中有6个,这是否意味着有6个对象未被正确销毁?

我不知所措,从哪里开始?

提前致谢。

2 个答案:

答案 0 :(得分:3)

您真正需要的信息是与每个泄漏对象关联的分配的堆栈跟踪。它们出现在屏幕截图中,但显示为地址而不是函数名称。启用调试信息,名称将显示给您。然后,您可以像在Delphi中使用FastMM一样跟踪问题。

答案 1 :(得分:2)

正如David Heffernan先前在其中一篇评论中提到的,应该有办法将这些地址转换为函数名称。

第一步是确保我已启用Generate debugging info for GDB由于某种原因未启用,然后我获得了这些函数名称。

在追踪地址后,他们将我带到了我的TList对象。现在我正在研究的这个项目实际上是在Delphi XE中启动的,但是我移植到了Lazarus,并且在XE中没有选择这些错误,但在释放我的TList Objects时我做到了这一点:

var
  P: Pointer;
begin
  for P in MyList do TMyListItem(P).Free;
end;

我没有安装XE进行测试,但我记得上面没有错误。

我还在Treeview中添加了对象(那些对象是MyList的指针),我没有释放它们。但即使这样做,我的泄漏仍然存在。

经过几个小时尝试不同的事情并接近放弃,我意识到我错过了一些简单的事情:

var
  P: Pointer;
begin
  for P in MyList do TMyListItem(P).Free;
  MyList.Free;
end;

我在Delphi中错过了那部分而且我很肯定它并没有抱怨任何泄漏,但在Lazarus / FPC我得到了大量的新泄漏。到目前为止,我所有的泄漏都已经消失了(希望如此),并且不会再回来了。

现在我收到这份泄漏报告,因为它报告了zero泄漏,因此看起来不那么可怕了:

enter image description here