develooper Front page | perl.perl5.porters | Postings from September 2013

[perl #119731] NEXT::DISTINCT can wrongly skip parent function calls

Thread Next
From:
Ryan Delany
Date:
September 12, 2013 05:16
Subject:
[perl #119731] NEXT::DISTINCT can wrongly skip parent function calls
Message ID:
rt-3.6.HEAD-1873-1378931914-1392.119731-75-0@perl.org
# New Ticket Created by  Ryan Delany 
# Please include the string:  [perl #119731]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org:443/rt3/Ticket/Display.html?id=119731 >


NEXT::DISTINCT can wrongly skip parent function calls when an object

is created at the same memory address as an old object. NEXT uses

the memory reference as part of a key into the $NEXT::SEEN hash, so

if the old object with the same memory reference is already in the

$NEXT::SEEN hash, NEXT::DISTINCT will think that the function call

has already been seen and it will skip it.

 

This can result in an object that did not call its parent init function,

if they are using NEXT::DISTINCT::_init().

 

This only happens when the $NEXT::SEEN variable exists already in the scope

when calling NEXT::DISTINCT::_init(). This can happen when you have two

inheritence trees and one calls the other. I have reproduced this with perl

version 5.10.1 on Linux and with perl version 5.18.1 on Windows.

 

The attached reproducer.pl will reproduce the problem. The second time a "Foo" object

is created, its parent's _init() will be skipped. It does this because it is created at the same

memory location as a previous object, so NEXT thinks it has already seen the function call

to its parent.

Output from attached reproducer.pl is below.

(notice how the second object does not have the 'parent' instance variable)

 

ref: Foo=HASH(0x2578990)

$VAR1 = bless( {

                 'parent' => 1

               }, 'Foo' );

 

 

 

ref: Foo=HASH(0x2578990)

$VAR1 = bless( {}, 'Foo' );





One way to fix the issue would be to assign a unique identifier for

the object in the NEXT code, since the memory reference is not always unique.

I was able to implement a fix using FieldHash, but there are other ways

to fix it as well. Another idea would be to make sure an object is cleared

from the $NEXT::SEEN hash when it is destroyed or cleaned up. 

 

I have attached a patch file of my changes.



---

Flags:

    category=library

    severity=low

    module=NEXT

---

Site configuration information for perl 5.18.1:

 

Configured by strawberry-perl at Tue Aug 13 17:19:29 2013.

 

Summary of my perl5 (revision 5 version 18 subversion 1) configuration:

   

  Platform:

    osname=MSWin32, osvers=4.0, archname=MSWin32-x64-multi-thread

    uname='Win32 strawberry-perl 5.18.1.1 #1 Tue Aug 13 17:18:28 2013 x64'

    config_args='undef'

    hint=recommended, useposix=true, d_sigaction=undef

    useithreads=define, usemultiplicity=define

    useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=undef

    use64bitint=define, use64bitall=undef, uselongdouble=undef

    usemymalloc=n, bincompat5005=undef

  Compiler:

    cc='gcc', ccflags =' -s -O2 -DWIN32 -DWIN64 -DCONSERVATIVE  -DPERL_TEXTMODE_SCRIPTS -DPERL_IMPLICIT_CONTEXT -DPERL_IMPLICIT_SYS -DUSE_PERLIO -fno-strict-aliasing -mms-bitfields',

    optimize='-s -O2',

    cppflags='-DWIN32'

    ccversion='', gccversion='4.7.3', gccosandvers=''

    intsize=4, longsize=4, ptrsize=8, doublesize=8, byteorder=12345678

    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12

    ivtype='long long', ivsize=8, nvtype='double', nvsize=8, Off_t='long long', lseeksize=8

    alignbytes=8, prototype=define

  Linker and Libraries:

    ld='g++', ldflags ='-s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib"'

    libpth=C:\strawberry\c\lib C:\strawberry\c\x86_64-w64-mingw32\lib

    libs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32

    perllibs=-lmoldname -lkernel32 -luser32 -lgdi32 -lwinspool -lcomdlg32 -ladvapi32 -lshell32 -lole32 -loleaut32 -lnetapi32 -luuid -lws2_32 -lmpr -lwinmm -lversion -lodbc32 -lodbccp32 -lcomctl32

    libc=, so=dll, useshrplib=true, libperl=libperl518.a

    gnulibc_version=''

  Dynamic Linking:

    dlsrc=dl_win32.xs, dlext=dll, d_dlsymun=undef, ccdlflags=' '

    cccdlflags=' ', lddlflags='-mdll -s -L"C:\strawberry\perl\lib\CORE" -L"C:\strawberry\c\lib"'

 

Locally applied patches:

    

 

---

@INC for perl 5.18.1:

    C:/strawberry/perl/site/lib

    C:/strawberry/perl/vendor/lib

    C:/strawberry/perl/lib

    .

 

---

Environment for perl 5.18.1:

    HOME (unset)

    LANG (unset)

    LANGUAGE (unset)

    LD_LIBRARY_PATH (unset)

    LOGDIR (unset)

    PATH=C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\Program Files\Microsoft Office\Office14;C:\Program Files (x86)\Windows Imaging\;C:\Program Files (x86)\Enterprise Vault\EVClient\;C:\strawberry\c\bin;C:\strawberry\perl\site\bin;C:\strawberry\perl\bin

    PERL_BADLANG (unset)

    SHELL (unset)


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About