in reply to Re^4: Is this absurd, or have I not RTFM?
in thread Is this absurd, or have I not RTFM?

This is not mere duplication of a printed message. As mentioned, when you enable the Devel::Peek statement you can see it's different references being provided in each call.

Can you add  STDOUT->autoflush(1); and show that output ?

Replies are listed 'Best First'.
Re^6: Is this absurd, or have I not RTFM?
by petermogensen (Sexton) on May 19, 2014 at 08:42 UTC
    Missing autoflushing may (as discussed else in this thread) explain why the "END DESTROY" line is not always printed. It doesn't explain the blow output of 2 different references being given to 2 calls to DESTROY in the same process though:
    ^C======= BEGIN DESTROY:11632======== 2014/05/19-10:36:43 Server closing! SV = IV(0x11ba5d8) at 0x11ba5e8 REFCNT = 1 FLAGS = (ROK,READONLY) RV = 0xe462b8 SV = PVHV(0xcf8880) at 0xe462b8 REFCNT = 1 FLAGS = (OBJECT,SHAREKEYS) STASH = 0xd10d40 "MyModule" ARRAY = 0x0 KEYS = 0 FILL = 0 MAX = 7 RITER = -1 EITER = 0x0 ======= BEGIN DESTROY:11632======== SV = IV(0x11ba4d0) at 0x11ba4e0 REFCNT = 1 FLAGS = (ROK,READONLY) RV = 0xe462b8 SV = PVHV(0xcf8880) at 0xe462b8 REFCNT = 1 FLAGS = (OBJECT,OOK,SHAREKEYS) STASH = 0xd10d40 "MyModule" ARRAY = 0xfa0e30 KEYS = 0 FILL = 0 MAX = 7 RITER = -1 EITER = 0x0 ============ END DESTROY:11632======== ======= BEGIN DESTROY:11631======== SV = IV(0xd103a0) at 0xd103b0 REFCNT = 1 FLAGS = (ROK,READONLY) RV = 0xe462b8 SV = PVHV(0xcf8880) at 0xe462b8 REFCNT = 1 FLAGS = (OBJECT,SHAREKEYS) STASH = 0xd10d40 "MyModule" ARRAY = 0x0 KEYS = 0 FILL = 0 MAX = 7 RITER = -1 EITER = 0x0 ============ END DESTROY:11631========
    The actual Perl object is also slightly changed... in a way I don't find meaningful... but then... I don't know the perlguts that well. I would primarily suspect a memory corruption reason for trashing the data. But it would be strange if such a problem never gave other symptoms with Net::Server::Prefork.

      Please try this

      #!/usr/bin/perl -- package MyModule; use Devel::Peek; sub new { my $obj = bless { '$$' => $$ }, shift; print "## $$ IN NEW $obj ##\n"; return $obj; } sub DESTROY { print "#### BEGIN DESTROY: $$ : @_ ####\n"; print Dump( @_ ); print "###### END DESTROY: $$ : @_ ######\n"; } 1; package MyServer; use parent qw[ Net::Server::PreFork ]; our $hardtodestroy = MyModule->new; sub child_finish_hook { undef $hardtodestroy; } 1; package main; STDOUT->autoflush(1); print "## this is perl $]\n"; MyServer->run( max_servers => 1, min_servers => 1, min_spare_servers => 0, max_spare_servers => 0 );
        2014/05/19-11:57:52 Server closing! #### BEGIN DESTROY: 13138 : MyModule=HASH(0x1441b78) #### SV = IV(0x190cba0) at 0x190cbb0 REFCNT = 1 FLAGS = (ROK,READONLY) #### BEGIN DESTROY: 13138 : MyModule=HASH(0x1441b78) #### SV = IV(0x190c810) at 0x190c820 REFCNT = 1 FLAGS = (ROK,READONLY) RV = 0x1441b78 SV = PVHV(0x1448880) at 0x1441b78 REFCNT = 1 FLAGS = (OBJECT,SHAREKEYS) STASH = 0x1460d40 "MyModule" ARRAY = 0x1459360 (0:7, 1:1) hash quality = 100.0% KEYS = 1 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 Elt "$$" HASH = 0x7f8f5659 SV = IV(0x1460268) at 0x1460278 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 13137 ###### END DESTROY: 13138 : MyModule=HASH(0x1441b78) ###### #### BEGIN DESTROY: 13137 : MyModule=HASH(0x1441b78) #### SV = IV(0x150bd48) at 0x150bd58 REFCNT = 1 FLAGS = (ROK,READONLY) RV = 0x1441b78 SV = PVHV(0x1448880) at 0x1441b78 REFCNT = 1 FLAGS = (OBJECT,SHAREKEYS) STASH = 0x1460d40 "MyModule" ARRAY = 0x1459360 (0:7, 1:1) hash quality = 100.0% KEYS = 1 FILL = 1 MAX = 7 RITER = -1 EITER = 0x0 Elt "$$" HASH = 0x7f8f5659 SV = IV(0x1460268) at 0x1460278 REFCNT = 1 FLAGS = (IOK,pIOK) IV = 13137 ###### END DESTROY: 13137 : MyModule=HASH(0x1441b78) ######

        So ... as it shows process 13138 is calling DESTROY twice for the same object. Apparently it gets interrupted by shutdown half way through the first invocation (but gets far enough to crash in other ways **). What I'm wondering about is what makes Perl retry the DESTROY method for the object at a later time.

        **: This means, that if the objects DESTROY method is an XS function you can manage to call free() on a C pointer during the first invocation before you get interrupted. ... and then calling free() again in the second invocation will cause glibc to complain loudly.