Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm getting a segfault which remains impervious to analysis. Perhaps someone can point me in the right direction?

My Perl script is billions of lines long and all attempts to reproduce the segfault in a shorter script have failed. The general format is:

use strict; use diagnostics; use warnings; use Glib qw(TRUE FALSE); BEGIN { require 5.008; use Archive::Extract; use Archive::Tar; use Compress::Zlib; use Encode qw(decode encode encodings find_encoding from_to); use Fcntl qw(:flock); use File::Basename; use File::Copy qw(copy move); use File::Copy::Recursive qw(dirmove); use File::Fetch; use File::Find; use File::HomeDir qw(my_home); use File::Path qw(remove_tree); use File::ShareDir ':ALL'; use File::ShareDir::Install; use Gnome2::Canvas; use Gnome2::Wnck; use Gtk2 '-init'; use Gtk2::Ex::Simple::List; use IO::Socket::INET; use IO::Socket::INET6; use IO::Socket::SSL; use IPC::Run qw(start); use JSON; use Math::Trig; use Module::Load qw(load); use Net::OpenSSH; use POSIX qw(ceil); use Regexp::IPv6 qw($IPv6_re); use Safe; use Scalar::Util qw(looks_like_number); use Socket qw(AF_INET SOCK_STREAM inet_aton sockaddr_in); use Symbol qw(qualify); use Storable qw(lock_nstore lock_retrieve); use Time::HiRes qw(gettimeofday); } sub hello_world(); Gtk2->main(); END { }

What I know so far:

Devel::Trace produces this output:

$ perl -d:Trace script.pl >trace 2>&1 >> lib/script.pm:6198: exit; >> /usr/share/perl/5.22/File/Temp.pm:731: local($., $@, $!, $^E, $ +?); >> /usr/share/perl/5.22/File/Temp.pm:732: cleanup(at_exit => 1); >> /usr/share/perl/5.22/File/Temp.pm:738: my %h = @_; >> /usr/share/perl/5.22/File/Temp.pm:739: my $at_exit = delete $h{ +at_exit}; >> /usr/share/perl/5.22/File/Temp.pm:740: $at_exit = 0 if not defi +ned $at_exit; >> /usr/share/perl/5.22/File/Temp.pm:741: { my @k = sort keys %h; +die "unrecognized parameters: @k" if @k } >> /usr/share/perl/5.22/File/Temp.pm:741: { my @k = sort keys %h; +die "unrecognized parameters: @k" if @k } >> /usr/share/perl/5.22/File/Temp.pm:741: { my @k = sort keys %h; +die "unrecognized parameters: @k" if @k } >> /usr/share/perl/5.22/File/Temp.pm:743: if (!$KEEP_ALL) { >> /usr/share/perl/5.22/File/Temp.pm:746: @{ $files +_to_unlink{$$} } : () ); >> /usr/share/perl/5.22/File/Temp.pm:747: foreach my $file (@fil +es) { >> /usr/share/perl/5.22/File/Temp.pm:761: @{ $dirs_t +o_unlink{$$} } : () ); >> /usr/share/perl/5.22/File/Temp.pm:762: my ($cwd, $cwd_to_remo +ve); >> /usr/share/perl/5.22/File/Temp.pm:763: foreach my $dir (@dirs +) { >> /usr/share/perl/5.22/File/Temp.pm:783: if (defined $cwd_to_re +move) { >> /usr/share/perl/5.22/File/Temp.pm:795: if exists $files_to_ +unlink{$$}; >> /usr/share/perl/5.22/File/Temp.pm:797: if exists $dirs_to_u +nlink{$$};

GDB produces this output:

(gdb) run Starting program: /usr/bin/perl script.pl [Thread debugging using libthread_db enabled] Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so +.1". [New Thread 0x7fffe5602700 (LWP 13152)] [New Thread 0x7fffe4e01700 (LWP 13153)] Thread 1 "perl" received signal SIGSEGV, Segmentation fault. emission_find (instance=0x116dfdf0, detail=0, signal_id=11) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./gobject/gsignal.c:824 824 /build/glib2.0-prJhLS/glib2.0-2.48.2/./gobject/gsignal.c: No su +ch file or directory. (gdb) bt #0 0x00007ffff6949820 in signal_emit_unlocked_R (instance=0x116dfdf0, + detail=0, signal_id=11) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./go +bject/gsignal.c:824 #1 0x00007ffff6949820 in signal_emit_unlocked_R (node=node@entry=0x24 +9d070, detail=detail@entry=0, instance=instance@entry=0x116dfdf0, emi +ssion_return=emission_return@entry=0x0, instance_and_params=instance_ +and_params@entry=0x7fffffffd7d0) at /build/glib2.0-prJhLS/glib2.0-2.4 +8.2/./gobject/gsignal.c:3513 #2 0x00007ffff6952d5c in g_signal_emit_valist (instance=<optimised ou +t>, signal_id=<optimised out>, detail=<optimised out>, var_args=var_a +rgs@entry=0x7fffffffd980) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./g +object/gsignal.c:3385 #3 0x00007ffff695308f in g_signal_emit (instance=instance@entry=0x116 +dfdf0, signal_id=<optimised out>, detail=detail@entry=0) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./gobject/gsignal.c:3441 #4 0x00007fffefb72db0 in gtk_object_dispose (gobject=0x116dfdf0 [GtkT +extView]) at /build/gtk+2.0-jJZIsQ/gtk+2.0-2.24.30/gtk/gtkobject.c:421 #5 0x00007ffff693cd25 in g_object_unref (_object=0x116dfdf0) at /build/glib2.0-prJhLS/glib2.0-2.48.2/./gobject/gobject.c:3146 #6 0x00007ffff6b9ae4a in () at /usr/lib/x86_64-linux-gnu/perl5/5.22/auto/Glib/Glib.so #7 0x00000000004bd45a in Perl_pp_entersub () #8 0x000000000043c2a8 in Perl_call_sv () #9 0x00000000004c1e03 in () #10 0x00000000004c2840 in Perl_sv_clear () #11 0x00000000004c2afd in Perl_sv_free2 () #12 0x00000000004c0c7b in () #13 0x00000000004c2eb4 in Perl_sv_clean_objs () #14 0x000000000043ee8b in perl_destruct () #15 0x000000000041caf3 in main ()

Valgrind produces this output:

==12589== Process terminating with default action of signal 11 (SIGSEG +V) ==12589== General Protection Fault ==12589== at 0x88B7820: signal_emit_unlocked_R (in /usr/lib/x86_64- +linux-gnu/libgobject-2.0.so.0.4800.2) ==12589== by 0x88C0D5B: g_signal_emit_valist (in /usr/lib/x86_64-li +nux-gnu/libgobject-2.0.so.0.4800.2) ==12589== by 0x88C108E: g_signal_emit (in /usr/lib/x86_64-linux-gnu +/libgobject-2.0.so.0.4800.2) ==12589== by 0x11102DAF: gtk_object_dispose (gtkobject.c:421) ==12589== by 0x88AAD24: g_object_unref (in /usr/lib/x86_64-linux-gn +u/libgobject-2.0.so.0.4800.2) ==12589== by 0x865DE49: ??? (in /usr/lib/x86_64-linux-gnu/perl5/5.2 +2/auto/Glib/Glib.so) ==12589== by 0x4BD459: Perl_pp_entersub (in /usr/bin/perl) ==12589== by 0x43C2A7: Perl_call_sv (in /usr/bin/perl) ==12589== by 0x4C1E02: ??? (in /usr/bin/perl) ==12589== by 0x4C283F: Perl_sv_clear (in /usr/bin/perl) ==12589== by 0x4C2AFC: Perl_sv_free2 (in /usr/bin/perl) ==12589== by 0x4C0C7A: ??? (in /usr/bin/perl) ==12589== ==12589== HEAP SUMMARY: ==12589== in use at exit: 272,606,526 bytes in 979,458 blocks ==12589== total heap usage: 3,010,187 allocs, 2,030,729 frees, 688,1 +61,553 bytes allocated ==12589== ==12589== LEAK SUMMARY: ==12589== definitely lost: 28,167 bytes in 595 blocks ==12589== indirectly lost: 35,893 bytes in 1,366 blocks ==12589== possibly lost: 173,410,130 bytes in 272,130 blocks ==12589== still reachable: 98,192,416 bytes in 699,586 blocks ==12589== of which reachable via heuristic: ==12589== length64 : 12,696 bytes in + 174 blocks ==12589== newarray : 828,744 bytes i +n 26,261 blocks ==12589== suppressed: 0 bytes in 0 blocks ==12589== Rerun with --leak-check=full to see details of leaked memory ==12589== ==12589== For counts of detected and suppressed errors, rerun with: -v ==12589== Use --track-origins=yes to see where uninitialised values co +me from ==12589== ERROR SUMMARY: 57 errors from 19 contexts (suppressed: 0 fro +m 0)

Replies are listed 'Best First'.
Re: Segfault in Glib/Gtk2 script
by hippo (Archbishop) on May 25, 2018 at 14:18 UTC

    Have you tried without Safe? It has quite a few outstanding bugs, some of which sound nasty (memory leaks, messing with %SIG, etc.).

    My Perl script is billions of lines long

    I hope for your sake that's hyperbole.

      >Have you tried without Safe?

      Yes. 'Safe' can be removed easily and the segfault is still present.

      >> My Perl script is billions of lines long

      >I hope for your sake that's hyperbole.

      Actually about 600,000 lines, but that includes empty space and comments.

        [My Perl script is] about 600,000 lines, but that includes empty space and comments.

        I hope for your sake that's a lot of empty space and comments. :)


        Give a man a fish:  <%-{-{-{-<

Re: Segfault in Glib/Gtk2 script
by Discipulus (Canon) on May 25, 2018 at 14:53 UTC
    Ouch! I'm really curious to know what your program does..

    my 2 neurocents (I'd send you a msg iinstead of a probably unuseful post,if you were a named user..): I read: In my opinion crash happens because of direct call of perl exit() in GTK signal handlers. from an ubuntu forum.

    They tell about a bug not always reproducible depending on library versions: in linux have you already tried to upgrade underlying libraries?

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.

      Ouch! I'm really curious to know what your program does..

      It's a telnet/MUD client. I'll be uploading the source code to CPAN as soon as this segfault is resolved.

      in linux have you already tried to upgrade underlying libraries?

      Yes, the problem on the Ubuntu forum you referenced does sound a lot like my issue. And replacing the 'exit' statement and using 'Gtk2->main_quit()' instead does indeed remove the segfault.

      (I had tried using both ->main_quit and exit together, unsuccesfully; it hadn't occured to me to remove 'exit' and keep ->main_quit).

        Hi, I'm a little rusty on the old Gtk stuff, but I just want to mention something that may help you further.

        You have to be careful with the return value of a delete_event, or any Gtk sub for that matter. Adding a 1 or 0 at the end of the sub can be needed sometimes.

        #These are different in a very subtle manner. $window->signal_connect( 'destroy', sub { Gtk2->main_quit() } ); $window->signal_connect(delete_event => sub { Gtk2->main_quit(); 1;});

        See Gtk delete_event for more details.

        From a previous problem like yours on the gtk maillist:


        Returns: TRUE to stop other handlers from being invoked for the
        event. FALSE to propagate the event further."

        .... a return of TRUE from the delete-event
        handler means "i handled this event, stop propagation."

        I'm not really a human, but I play one on earth. ..... an animated JAPH
Re: Segfault in Glib/Gtk2 script
by choroba (Cardinal) on May 25, 2018 at 14:09 UTC
    Are all the modules really needed to reproduce the issue?

    BTW, what does it mean to have use statements in a BEGIN block?

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

      >Are all the modules really needed to reproduce the issue?

      I have already tried cutting out all unnecessary blocks of code, leaving just essential features. For modules, these are the absolute minimum required to run the script and produce the segfault

      use Archive::Extract; use Archive::Tar; use Encode qw(decode encode encodings find_encoding from_to); use File::Basename; use File::Copy qw(copy move); use File::HomeDir qw(my_home); use File::Path qw(remove_tree); use Gnome2::Canvas; use Gnome2::Wnck; use Gtk2 '-init'; use IPC::Run qw(start); use Storable qw(lock_nstore lock_retrieve);

      >BTW, what does it mean to have use statements in a BEGIN block?

      It's not necessary. Removing the BEGIN {} section from the script does not remove the segfault.