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

3
在Delphi XE中,我总是使用ReportMemoryLeaksOnShutDown来检测退出应用程序时的任何泄漏,我的大部分项目都相当小,找到泄漏通常不太困难。
在Lazarus中没有这样的选项,但我刚刚发现了一个名为Heaptrcon的选项,在此页面上可以找到更多信息:http://wiki.lazarus.freepascal.org/Profiling 在项目选项>链接中,我设置了(-gh)标志,现在我的担忧变成了现实。我想发布代码,但由于有很多不同的类和单元,我不知道从哪里开始修复这些泄漏问题,这是我所处理过的最大的一个项目。
这是一些泄漏的截图: enter image description here 我的调试技能几乎为零,到目前为止,我已经查看了我创建的每个对象或类,并检查它是否已被释放。因为我正在使用许多TLists和指针/对象等,泄漏可能来自任何地方。
有没有线索或提示从哪里开始寻找?我正在查看每个块的调用堆栈大小为16,有6个,这是否意味着有6个对象未被正确销毁?
我无从下手,从哪里开始?
提前感谢您的帮助。

1
你真的需要将那些地址转换为函数名称。肯定有一种方法可以使用 FPC 来实现这一点。 - David Heffernan
@DavidHeffernan 我不知道,我需要看看是否可能,这将会帮助很大。编辑:我已经打开了调试信息,现在有函数名称了。我真的想自己尝试解决这个问题,所以如果现在能把问题搁置一下,也许可以吗? - user1175743
1
"Lineinfo" (-gl)是需要注意的FPC参数。 - Marco van de Voort
@MarcovandeVoort 我发现到处都有内存泄漏,一整天都在尝试调试。我似乎修复了很多问题,但新的问题又不断出现 :( - user1175743
我所知道的 memprofiling(除了 Delphi)唯一的问题是主程序中的内存泄漏并不总是能够正确地被检测到。(据我所知,这可能与单元的终结顺序有关,包括内存单元和局部于主程序的全局变量的终结顺序存在某些问题或变量) - Marco van de Voort
2个回答

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

肯定的是,树形视图不会释放Node.Data中的对象。 - David Heffernan

2

正如David Heffernan在早期评论中提到的那样,应该有一种方法将这些地址转换为函数名称。

第一步是确保我已启用了为GDB生成调试信息,由于某种原因它没有被启用,然后我得到了这些函数名称。

在追踪这些地址后,它们引导我到我的TList对象。现在,我正在使用Delphi XE开始的这个项目,但我正在将其移植到Lazarus上,在XE中并没有发现这些错误,但当我释放我的TList对象时,我做了这件事:

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中,我发现了许多新的泄漏。目前为止,所有的泄漏都已经被解决了(希望如此),不会再出现。

现在我得到了这个泄漏报告,看起来并不可怕,因为它报告了个泄漏:

enter image description here


1
感谢分享您的经验! - jwdietrich

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