# New Ticket Created by Steve Fink # Please include the string: [perl #31493] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org:80/rt3/Ticket/Display.html?id=31493 >
--- osname= linux osvers= 2.4.21-1.1931.2.382.entsmp arch= i386-linux-thread-multi cc= gcc 3.2.2 20030222 (Red Hat Linux 3.2.2-5) --- Flags: category=core severity=high ack=no --- I have a dynamic PMC named 'Match' that extends the PerlHash PMC. I have occasionally been seeing "destroy() not implemented in class 'Match'" on program shutdown. Match does not define destroy(), nor does it set the active destroy flag. Looking deeper, I find that it's trying to dispose of a PMC with its ->obj.flags member completely trashed, and in particular it has an erroneous bit set for the active destroy flag. I won't go through all the details of what I looked at (though I'll post them in my blog eventually), but what's happening is that this line (from perlhash.pmc's clone() implementation) is corrupting the flags field: ((Hash*)PMC_struct_val(dest))->container = dest; The problem is that the dest PMC contains a Hash structure in its struct_val field, but the address of the Hash is only 0x18 bytes before the address of the PMC itself, and Hashes are 0x40 bytes each. The offset of the container field within a Hash is 0x20, and the offset of the flags field within a PMC is 0x04. So assigning to that container field overwrites the flags field, since 0x18 + 0x04 == 0x20. It seems like an initialization ordering problem, especially since I can make the problem go away by changing the clone() method from PMC* clone () { PMC* dest = pmc_new_noinit(INTERP, SELF->vtable->base_type); PObj_custom_mark_SET(dest); ((Hash*)PMC_struct_val(dest))->container = dest; hash_clone(INTERP, (Hash *)PMC_struct_val(SELF), (Hash**)&PMC_struct_val(dest)); return dest; } to PMC* clone () { PMC* dest = pmc_new(INTERP, SELF->vtable->base_type); hash_clone(INTERP, (Hash *)PMC_struct_val(SELF), (Hash**)&PMC_struct_val(dest)); return dest; } But I'm not sure why, and I'm not sure if this is a bug in perlhash's clone(), or some weird side effect of using dynamic PMCs. (For now, I'm just reimplementing clone() in my subclass.) --- Summary of my parrot 0.1.0 configuration: configdate='Wed Sep 8 23:20:30 2004' Platform: osname=linux, archname=i386-linux-thread-multi jitcapable=1, jitarchname=i386-linux, jitosname=LINUX, jitcpuarch=i386 execcapable=1 perl=/usr/bin/perl Compiler: cc='ccache gcc', ccflags='-D_REENTRANT -D_GNU_SOURCE -DTHREADS_HAVE_PIDS -DDEBUGGING -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -I/usr/include/gdbm -O1', Linker and Libraries: ld='gcc', ldflags=' -L/usr/local/lib', cc_ldflags='', libs='-lnsl -ldl -lm -lpthread -lcrypt -lutil -lrt -lgmp' Dynamic Linking: so='.so', ld_shared='-shared -L/usr/local/lib -fPIC', ld_shared_flags='' Types: iv=long, intvalsize=4, intsize=4, opcode_t=long, opcode_t_size=4, ptrsize=4, ptr_alignment=1 byteorder=1234, nv=double, numvalsize=8, doublesize=8 --- Environment: HOME LANG LANGUAGE LC_ALL LD_LIBRARY_PATH LOGDIR PATH SHELL