如何在 Mac OS X 上获取内存泄漏的行编号堆栈跟踪?

发布于 2024-11-08 21:39:32 字数 1045 浏览 0 评论 0原文

我已经设法让 Xcode leaks 工具报告我的命令行 GCC Ada 程序中的泄漏(通过在末尾添加 delay 11.0;leaks 进行检查),然后

$ export MallocStackLogging=1
$ (./foobar &)  && leaks foobar

导致(摘录),

Process 52027: 18 nodes malloced for 2053 KB
Process 52027: 2 leaks for 32 total leaked bytes.
Leak: 0x1002000c0  size=16  zone: DefaultMallocZone_0x100175000 string '*'
        Call stack: [thread 0x7fff70bbcca0]: | start | main | _ada_foobar | __gnat_malloc | malloc | malloc_zone_malloc 
Leak: 0x1002000d0  size=16  zone: DefaultMallocZone_0x100175000 string 'T'
        Call stack: [thread 0x7fff70bbcca0]: | start | main | _ada_foobar | __gnat_malloc | malloc | malloc_zone_malloc 

这比没有好得多,但行数会大大改善。

有没有我应该使用的构建选项?如果 Ada 编译器(FSF GCC 4.6.0,不是来自 Apple)与 Xcode 集成,效果会更好吗?

这是基于 10.6.7、Xcode 3.2.6 的 x86_64 构建。使用 -g 没有什么区别。

调用栈中,maingnatmake生成的main()_ada_foobar是Ada程序,其中泄漏确实发生了。其他帧来自运行时系统。

I've managed to get the Xcode leaks tool to report leaks in my command-line GCC Ada program (by adding delay 11.0; at the end to let leaks make its checks) and then

$ export MallocStackLogging=1
$ (./foobar &)  && leaks foobar

which leads to (excerpted)

Process 52027: 18 nodes malloced for 2053 KB
Process 52027: 2 leaks for 32 total leaked bytes.
Leak: 0x1002000c0  size=16  zone: DefaultMallocZone_0x100175000 string '*'
        Call stack: [thread 0x7fff70bbcca0]: | start | main | _ada_foobar | __gnat_malloc | malloc | malloc_zone_malloc 
Leak: 0x1002000d0  size=16  zone: DefaultMallocZone_0x100175000 string 'T'
        Call stack: [thread 0x7fff70bbcca0]: | start | main | _ada_foobar | __gnat_malloc | malloc | malloc_zone_malloc 

which is a great deal better than nothing, but would be considerably improved with line numbers.

Are there any build options I should have used? Would it work better if the Ada compiler (FSF GCC 4.6.0, not from Apple) was integrated with Xcode?

This is an x86_64 build on 10.6.7, Xcode 3.2.6. Using -g makes no difference.

In the call stack, main is the main() generated by gnatmake, _ada_foobar is the Ada program in which the leak actually occurs. The other frames are from the run time system.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青春有你 2024-11-15 21:39:32

好吧,这里的主要问题正是您拥有哪个编译器。您从 ACT 获得的 Gnat 版本带有一个链接库 addr2line.lib,可用于在运行时生成符号回溯。

您从 FSF 发行版获得的 Gnat 版本没有该库。不过,仍然有 Gnu 的“binutils”附带的 addr2line 程序。您的 Mac 设置中确实可以使用该功能,对吧?

如果您将十六进制地址输入该程序,它应该报告您想要的符号信息。您可能需要稍微重新格式化您的 leaks 输出,以便 addr2line 接受它。

Well, the chief issue here is exactly which compiler you have. The versions of Gnat you get from ACT come with a link libraray addr2line.lib that can be used to produce symbolic tracebacks at runtime.

The versions of Gnat you get from the FSF distributions don't have that library. However, there is still the addr2line program that comes with Gnu's "binutils". You do have that available for you on your Mac setup, right?

If you feed your hex addresses into that program, it should report the symbolic information you want. You may have to reformat your leaks output a bit for addr2line to accept it.

不喜欢何必死缠烂打 2024-11-15 21:39:32

Valgrind 3.7.0 适用于 Mac OS X;我的代码测试是

with Ada.Text_IO; use Ada.Text_IO;
procedure Leaker is
   type P is access Integer;
   procedure Inner is
      V : P;
   begin
      Put_Line ("allocating for 42");
      V := new Integer'(42);
      Put_Line ("allocating for 0");
      V := new Integer'(0);
      Put_Line ("done.");
   end Inner;
begin
   Inner;
end Leaker;

,我运行以

valgrind --leak-check=full --dsymutil=yes ./leaker

获得一份报告,其中包括

8 bytes in 2 blocks are definitely lost in loss record 2 of 9
   at 0xB823: malloc (vg_replace_malloc.c:266)
   by 0x100010CC7: __gnat_malloc (s-memory.adb:92)
   by 0x100001C7D: _ada_leaker (leaker.adb:14)
   by 0x100001BAA: main (b~leaker.adb:191)

leaker.adb:14 是对 Inner 的调用。

Valgrind 3.7.0 is available for Mac OS X; my code test was

with Ada.Text_IO; use Ada.Text_IO;
procedure Leaker is
   type P is access Integer;
   procedure Inner is
      V : P;
   begin
      Put_Line ("allocating for 42");
      V := new Integer'(42);
      Put_Line ("allocating for 0");
      V := new Integer'(0);
      Put_Line ("done.");
   end Inner;
begin
   Inner;
end Leaker;

and I ran with

valgrind --leak-check=full --dsymutil=yes ./leaker

to get a report including

8 bytes in 2 blocks are definitely lost in loss record 2 of 9
   at 0xB823: malloc (vg_replace_malloc.c:266)
   by 0x100010CC7: __gnat_malloc (s-memory.adb:92)
   by 0x100001C7D: _ada_leaker (leaker.adb:14)
   by 0x100001BAA: main (b~leaker.adb:191)

leaker.adb:14 is the call to Inner.

相对绾红妆 2024-11-15 21:39:32

虽然不如 valgrind 具有决定性,如此处所示,但可以Spawn 没有延迟leaks实例,如下所示。 Spawn 块,允许 leaks 在继续之前结束。在最好的情况下,这是验证没有发现泄漏的快速方法;如果没有,配对调用可以缩小对违规代码的搜索范围。

代码:

with Ada.Text_IO; use Ada.Text_IO;
with GNAT.OS_Lib; use GNAT.OS_Lib;
procedure Leaker is
   type P is access Integer;
   procedure Inner is
      V : P;
   begin
      Put_Line ("allocating for 42");
      V := new Integer'(42);
      Put_Line ("allocating for 0");
      V := new Integer'(0);
      Put_Line ("done.");
   end Inner;
   Result    : Integer;
   Command   : constant String        := "/usr/bin/leaks";
   Arguments : constant Argument_List :=
     (1 => new String'("-quiet"), 2 => new String'("leaker"));
begin
   Result := Spawn (Command, Arguments);
   Inner;
   Result := Spawn (Command, Arguments);
end Leaker;

控制台:

leaks Report Version: 4.0
Process 46711: 156 nodes malloced for 8 KB
Process 46711: 0 leaks for 0 total leaked bytes.

allocating for 42
allocating for 0
done.
leaks Report Version: 4.0
Process 46711: 158 nodes malloced for 8 KB
Process 46711: 2 leaks for 32 total leaked bytes.

    2 (32 bytes) << TOTAL >>
      1 (16 bytes) ROOT LEAK: 0x7f8f83504080 [16]  length: 1  "*"
      1 (16 bytes) ROOT LEAK: 0x7f8f83504090 [16]

Although less dispositive than valgrind, illustrated here, it's possible to Spawn an instance of leaks without delay as shown below. Spawn blocks, allowing leaks to conclude before proceeding. In the best case, it's a quick way to verify that no leaks were found; if not, paired calls can narrow the search for offending code.

Code:

with Ada.Text_IO; use Ada.Text_IO;
with GNAT.OS_Lib; use GNAT.OS_Lib;
procedure Leaker is
   type P is access Integer;
   procedure Inner is
      V : P;
   begin
      Put_Line ("allocating for 42");
      V := new Integer'(42);
      Put_Line ("allocating for 0");
      V := new Integer'(0);
      Put_Line ("done.");
   end Inner;
   Result    : Integer;
   Command   : constant String        := "/usr/bin/leaks";
   Arguments : constant Argument_List :=
     (1 => new String'("-quiet"), 2 => new String'("leaker"));
begin
   Result := Spawn (Command, Arguments);
   Inner;
   Result := Spawn (Command, Arguments);
end Leaker;

Console:

leaks Report Version: 4.0
Process 46711: 156 nodes malloced for 8 KB
Process 46711: 0 leaks for 0 total leaked bytes.

allocating for 42
allocating for 0
done.
leaks Report Version: 4.0
Process 46711: 158 nodes malloced for 8 KB
Process 46711: 2 leaks for 32 total leaked bytes.

    2 (32 bytes) << TOTAL >>
      1 (16 bytes) ROOT LEAK: 0x7f8f83504080 [16]  length: 1  "*"
      1 (16 bytes) ROOT LEAK: 0x7f8f83504090 [16]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文