Devo aver fatto perl
molto turbato perché mi sta dando un messaggio di errore che non è documentato in perldiag
:Che cosa significa "PmmREFCNT_dec: REFCNT decrementato sotto 0" significa?
PmmREFCNT_dec: RefCnt decrementato di sotto di 0 per 53a6930 !.
A seconda della sua stato d'animo, a volte questo è seguito da:
*** glibc rilevato ***/usr/bin/perl: doppio libero o la corruzione (prec!): 0x0000000004e58a60 *
... o più chiaramente da:
Segmentation fault
Questo, chiaramente, è fatale, ma l'ho anche testato per essere intercettabile. Quando utilizzo Try::Tiny
, rileverò sempre l'errore nello stesso punto, ma quando non lo utilizzo, vengono eseguite ulteriori istruzioni prima che si verifichi l'arresto anomalo. Inoltre, anche se il mio modulo è completamente determinista e sono abbastanza sicuro che tutte le dipendenze siano uguali, l'errore non si verifica tutte le volte.
Sfortunatamente, il modulo che mi sta dando questo problema è enorme, con molte dipendenze e non sono stato in grado di replicare il problema su un esempio più piccolo. Quindi, non posso chiedere aiuto per il debug, ma se qualcuno ha familiarità con gli interni di Perl sa in quali circostanze si verifica questo errore, questo può aiutare me (o chiunque altro vedrà mai questo messaggio) a trovare la fonte del problema e/o una soluzione.
Nel caso sia utile, l'idea generale è questa. Ho due classi, chiamiamole Thing
e SetOfThings
. SetOfThings
ha un attributo che è un insieme di istanze Thing
. Entrambi classe ha anche un metodo explode
che fa qualcosa di simile:
# SetOfThings
sub explode {
my $self = shift;
my $new = dclone $self;
delete $new->{'some_attribute'};
$new->set_of_things(map { $_->explode } $self->constraints);
return $new;
}
# Thing
sub explode {
my $self = shift;
return map { new Thing(do_something_fancy) } keys %$self;
}
L'errore di solito sembra verificarsi quando si chiama SetOfThings::explode
o quando si chiama SetOfThings::set_of_things
come un getter.
Edit: Backtrace
Non credo io sono abbastanza competente per interpretarlo, ma ho ottenuto un backtrace da gdb
:
#0 0x00007ffff70a6094 in ??() from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff70a76a8 in ??() from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00007ffff70aab1c in free() from /lib/x86_64-linux-gnu/libc.so.6
#3 0x00007ffff7b0869b in Perl_hv_undef_flags() from /usr/lib/libperl.so.5.14
#4 0x00007ffff7b1ae66 in Perl_sv_clear() from /usr/lib/libperl.so.5.14
#5 0x00007ffff7b1b292 in Perl_sv_free2() from /usr/lib/libperl.so.5.14
#6 0x00007ffff7b04bc3 in Perl_hv_free_ent() from /usr/lib/libperl.so.5.14
#7 0x00007ffff7b04e6e in ??() from /usr/lib/libperl.so.5.14
#8 0x00007ffff7b08683 in Perl_hv_undef_flags() from /usr/lib/libperl.so.5.14
#9 0x00007ffff7b1ae66 in Perl_sv_clear() from /usr/lib/libperl.so.5.14
#10 0x00007ffff7b1b292 in Perl_sv_free2() from /usr/lib/libperl.so.5.14
#11 0x00007ffff7b42cef in Perl_leave_scope() from /usr/lib/libperl.so.5.14
#12 0x00007ffff7b11112 in Perl_pp_leave() from /usr/lib/libperl.so.5.14
#13 0x00007ffff7b0bce6 in Perl_runops_standard() from /usr/lib/libperl.so.5.14
#14 0x00007ffff7aad815 in perl_run() from /usr/lib/libperl.so.5.14
#15 0x0000000000400f89 in main()
Edit 2: Valgrind backtrace
Questo è quello che ho ottenuto dall'esecuzione di valgrind
. Anche se non sono ancora sicuro di quello che sta succedendo, almeno ora so chi dare la colpa.:-)
==27226== Invalid free()/delete/delete[]/realloc()
==27226== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27226== by 0xA138F42: PmmREFCNT_dec (in /usr/lib/perl5/auto/XML/LibXML/LibXML.so)
==27226== by 0xA11D3FA: XS_XML__LibXML__Node_DESTROY (in /usr/lib/perl5/auto/XML/LibXML/LibXML.so)
==27226== by 0x4EE770B: Perl_pp_entersub (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4E7AB90: Perl_call_sv (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EEDBD8: Perl_sv_clear (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EEE291: Perl_sv_free2 (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4ED7BC2: Perl_hv_free_ent (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4ED7E6D: ??? (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EDB682: Perl_hv_undef_flags (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EEDE65: Perl_sv_clear (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EEE291: Perl_sv_free2 (in /usr/lib/libperl.so.5.14.2)
==27226== Address 0x17d0b710 is 0 bytes inside a block of size 32 free'd
==27226== at 0x4C27D4E: free (vg_replace_malloc.c:427)
==27226== by 0xA138F42: PmmREFCNT_dec (in /usr/lib/perl5/auto/XML/LibXML/LibXML.so)
==27226== by 0xA11D3FA: XS_XML__LibXML__Node_DESTROY (in /usr/lib/perl5/auto/XML/LibXML/LibXML.so)
==27226== by 0x4EE770B: Perl_pp_entersub (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4E7AB90: Perl_call_sv (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EEDBD8: Perl_sv_clear (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EEE291: Perl_sv_free2 (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4ED7BC2: Perl_hv_free_ent (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EDA919: Perl_hv_common (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4F0EEC7: Perl_pp_delete (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4EDECE5: Perl_runops_standard (in /usr/lib/libperl.so.5.14.2)
==27226== by 0x4E80814: perl_run (in /usr/lib/libperl.so.5.14.2)
È un errore in Perl o in un modulo XS. Una variabile deve essere liberata quando il suo conteggio dei riferimenti raggiunge lo zero, ma qualcosa ha tentato di decrementare il conteggio dei riferimenti di una variabile quando era già zero. – ikegami
'valgrind' può essere utile utile. Una traccia stack da 'gdb' su segfault può essere utile. – ikegami
Hai avuto ragione, come al solito, grazie! Non sono abbastanza bravo in un programmatore C per capire cosa sta succedendo qui, ma 'valgrind' è stato in grado di dire quale sia il modulo XS da incolpare. – scozy