为什么使用`DEBUG_LEAKING_SCALARS`编译perl时不会报告内存泄漏?

6

我按照这里所描述的方法,使用DEBUG_LEAKING_SCALARS编译perl。

案例1
我遵循此文档测试内存泄漏报告:

env PERL_DESTRUCT_LEVEL=2 valgrind perl -e '@x; $x[0]=\@x'
==7216== Memcheck, a memory error detector
==7216== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7216== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==7216== Command: perl -e @x;\ $x[0]=\\@x
==7216== 
==7216== 
==7216== HEAP SUMMARY:
==7216==     in use at exit: 0 bytes in 0 blocks
==7216==   total heap usage: 1,310 allocs, 1,310 frees, 171,397 bytes allocated
==7216== 
==7216== All heap blocks were freed -- no leaks are possible
==7216== 
==7216== For counts of detected and suppressed errors, rerun with: -v
==7216== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

没有报告。

案例2
我甚至在我的XS子程序中执行这个操作。确切地说:

#define PERL_NO_GET_CONTEXT
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "XSUtils.h"
#include "ppport.h"

void
call_perl() {
    SV *sv;
    sv =  sv_2mortal( newSVpv( "XS::Utils::hello", 0 ) );

    newSViv( 323 );     //<<<< SHOULD LEAK
    printf( "Hi 3\n" );

    ENTERSCOPE;
    CALLPERL( sv , G_DISCARD|G_NOARGS );
    LEAVESCOPE;
}

MODULE = XS::Utils                    PACKAGE = XS::Utils

void
test()
    CODE:
        call_perl();

仓库链接

$ env PERL_DESTRUCT_LEVEL=2 valgrind perl -Iblib/arch/ -Iblib/lib -MXS::Utils -e 'XS::Utils::test()' 
==7308== Memcheck, a memory error detector
==7308== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7308== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==7308== Command: perl -Iblib/arch/ -Iblib/lib -MXS::Utils -e XS::Utils::test()
==7308== 
Hi 3
Hello
==7308== 
==7308== HEAP SUMMARY:
==7308==     in use at exit: 1,502 bytes in 5 blocks
==7308==   total heap usage: 12,876 allocs, 12,871 frees, 1,945,298 bytes allocated
==7308== 
==7308== LEAK SUMMARY:
==7308==    definitely lost: 0 bytes in 0 blocks
==7308==    indirectly lost: 0 bytes in 0 blocks
==7308==      possibly lost: 0 bytes in 0 blocks
==7308==    still reachable: 1,502 bytes in 5 blocks
==7308==         suppressed: 0 bytes in 0 blocks
==7308== Rerun with --leak-check=full to see details of leaked memory
==7308== 
==7308== For counts of detected and suppressed errors, rerun with: -v
==7308== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

没有任何报告

CASE 3
我修复了模块Devel::LeakTraceFIX):

$ perl -MDevel::LeakTrace -Iblib/arch/ -Iblib/lib -MXS::Utils -e 'XS::Utils::test()' 
Hi 3
Hello

没有任何报告

案例4
我只发现Test::LeakTrace能够胜任:

$ perl -MTest::LeakTrace::Script=-verbose -Iblib/arch/ -Iblib/lib -MXS::Utils -e 'XS::Utils::test()' 
Hi 3
Hello
leaked SCALAR(0x208e1c0) from -e line 1.
ALLOCATED at -e:1 by entersub (parent 0x0); serial 9642
SV = IV(0x208e1b0) at 0x208e1c0
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 323

为什么Perl中的内置工具没有报告泄漏问题?
我做错了什么?如何使用DEBUG_LEAKING_SCALARS工具调试泄漏的内存?


你知道吗,也许你应该在irc.perl.org的#p5p频道里逛一逛。我有一种感觉,那里的人对你正在做的这些东西比我们这里更熟悉。 :) - simbabque
2
@simbabque...,但是为了参考,知道答案也很好...... :) :) - clt60
@jm666 绝对没错。他这样做非常有用,但每次过一两天后他都会发布自己的答案。如果加入一些关于他正在做什么的上下文,它就可以成为一个技术博客。 :D 请继续 Eugen。 - simbabque
@simbabque,你的点赞给了我动力!=) - Eugen Konkov
好的,我被说服了。给你吧。 :P - simbabque
1个回答

1

实际上不是一个答案,而是来自 Dave Mitchell 的回复:

DEBUG_LEAKING_SCALARS 的主要目的并不是列出泄漏的标量
(!!)
它的主要目的是帮助追踪与泄漏的标量和引用计数问题有关的事情。它的两个主要特点是将 SV 分配从宏变成函数,以便您可以轻松地附加断点;以及它向每个 SV 添加了插装,显示它的分配位置(如 Devel::Peek 所示)。

但我不知道该调试什么,因为我不知道有什么东西在泄漏。就像上面描述的第1到3种情况一样。我确信:

newSViv( 323 );

没有泄漏。

所以DEBUG_LEAKING_SCALARS应该列出泄漏的标量

此外,我在perl提交历史记录中找到了这条注释:

-[24088] By:davem on 2005/03/28 21:38:44
- 日志:扩展-DDEBUG_LEAKING_SCALARS以仪器化每个SV的创建

对于this任务,这将非常有用。


这就解释了为什么DEBUG_LEAKING_SCALARS不会列出泄漏(因为它的目的是使调试泄漏更容易,而不是首先识别泄漏),但它提出了可疑和未经解释的声明,即DEBUG_LEAKING_SCALARS应该列出泄漏的标量,并且它没有解释为什么旨在查找泄漏的工具(valgrind和Devel::LeakTrace)没有发现它。 - ikegami

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