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

How do I get a stack trace from "Thread 1 terminated abnormally"? As the error may well be in XSUB C code, I'd like to trap the fault in gdb. My first attempt was to stub out all calls to sigaction() in my custom compiled perl to disable any signal handlers, however, I get the same behavior. The answer I would like is to configure perl or the threads object to exit the process on any failure. Btw: I've already tried to put logs everywhere I think of. It is as if there is a ghost between to lines in my perl script that is jumping out at me for Halloween.

Replies are listed 'Best First'.
Re: stack trace from thread exit
by zentara (Cardinal) on Oct 25, 2010 at 18:26 UTC
    The answer I would like is to configure perl or the threads object to exit the process on any failure

    From perldoc threads v1.75:

    $thr->error() Threads are executed in an "eval" context. This method will return "undef" if the thread terminates normally. Otherwise, it returns the value of $@ associated with the thread's execution status in its "eval" context.

    and you might want to look at

    threads->create({'exit' => 'thread_only'}, ...) This overrides the default behavior of "exit()" inside the newly crea +ted thread only. ...... with this setting, calling "exit()" causes only the thread to t +erminate

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: stack trace from thread exit
by BrowserUk (Patriarch) on Oct 25, 2010 at 19:15 UTC

    Would this help? (I don't use gdb):

    #! perl -slw use strict; use threads; use Carp; sub thread { my $x = shift; eval{ my $y = 100 / $x; } or croak "$@"; } async( \&thread, $_ )->detach for reverse 0 .. 3; sleep 10 __END__ C:\test>junk Thread 4 terminated abnormally: Illegal division by zero at C:\test\ju +nk.pl line 9. at C:\test\junk.pl line 8 thread 4 main::thread(0) called at C:\test\junk.pl line 12 thread 4 eval {...} called at C:\test\junk.pl line 12 thread 4 ;

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: stack trace from thread exit
by ig (Vicar) on Oct 25, 2010 at 21:48 UTC

    To get a core dump when a warning is issued, set $SIG{__WARN__} to produce a core dump. For example:

    use warnings; my @x = qw(a b c); $SIG{__WARN__} = sub { print "got a warning: $_[0]\n"; CORE::dump; }; for (0..3) { print "$x[$_]\n"; }

    Remember to set your process limit to allow the core file to be produced (ulimit -c if you are using bash, see the man bash for details of ulimit).

      So, ig, you’re saying that you find core-dumps to be a useful diagnostic technique with regard to Perl programs?   Interesting...   Could you elaborate on (or reference to) how you use them in this context?

        Could you elaborate on (or reference to) how you use them in this context?

        I am not sure which context you refer to by this context.

        With regard to Perl programs in general, I have rarely used gdb and, even less often, core dumps: to investigate perl initialization, lexing and parsing, to study and customize the regular expression engine and once to track down a bug in PerlIO that produced a core dump during initialization when attempting to read a UTF-16 encoded file. I don't recall any other use at the moment...

        Much more often, I use logging and test cases to investigate Perl programs and programs in general. I developed my debugging habits about the time Brian Kernighan wrote: The most effective debugging tool is still careful thought, coupled with judiciously placed print statements., and I remain very much in that camp. But there have been times when I have found debuggers and core dumps very helpful. For example, I once found a bug in the perl tokenizer that could not be isolated with test Perl programs and print statements, and tracing the execution was much more effective that merely reading the source in toke.c.

        I haven't done much with XS, but once outside the realm of the Perl interpreter gdb can be a helpful tool.

        When I do use them with Perl programs (gdb and core dumps) I do so as I would for any other program. There are various manuals and tutorials available on the net, including http://www.gnu.org/software/gdb/documentation/ and http://www.cs.cmu.edu/~gilpin/tutorial/. I always build perl from source with -g flag and generally investigate the issue by other means first. While it is possible to attach gdb to live programs, I very much prefer small test cases run in isolation.

        If by this context you mean the situation of the OP, I have not used gdb or core dumps to investigate crashing threaded Perl programs using possibly buggy XS modules. I would try other means to isolate the fault first, but might use gdb if core files were being produced, at least to get some idea where in the code the fault was occuring, if other approaches proved unsatisfactory.

        I was merely responding to the OP who said: I'd like to trap the fault in gdb. Given that specific objective and the warning, I thought a core dump produced in the context of the warning might be what the OP was wanting.

        The test program I provided produces a core dump, if resource limits permit (I am assuming *nix system). It is easily accessed in gdb with:

        gdb /usr/bin/perl core

        (Substitute the path to the relevant instance of perl on your system.)

        The C stack is easily displayed with the bt command. Beyond that, one would have to know perl and the relevant Perl and XS programs in some detail to know where to look.

        ig was responding to my request. Because I suspect XSUB C functions, I was looking to get a gdb bt; and here it is:
        Thread 2 (Thread 25070): #0 0x0000000000446c34 in Perl_hv_common () No symbol table info available. #1 0x0000000000447fee in Perl_hv_common_key_len () No symbol table info available. #2 0x00000000004d3b3f in Perl_gv_fetchmeth () No symbol table info available. #3 0x00000000004d3d32 in Perl_gv_fetchmeth () No symbol table info available. #4 0x00000000004d5dae in Perl_Gv_AMupdate () No symbol table info available. #5 0x00000000004613cb in Perl_sv_bless () No symbol table info available. #6 0x0000000000461836 in Perl_newSVrv () No symbol table info available. #7 0x0000000000468ff6 in Perl_sv_setref_pv () No symbol table info available. #8 0x00007f6c0548b63e in XS_Net__SSH2__new () from /auto/share/perl/5 +.8.9/lib/site_perl/5.8.9/x86_64-linux-thread-multi/auto/Net/SSH2/SSH2 +.so No symbol table info available. #9 0x00000000004547fb in Perl_pp_entersub () No symbol table info available. #10 0x0000000000452d06 in Perl_runops_standard () No symbol table info available. #11 0x00000000004507ce in Perl_call_sv () No symbol table info available. #12 0x00007f6c05aab899 in S_ithread_run () from /auto/share/perl/5.8.9 +/lib/5.8.9/x86_64-linux-thread-multi/auto/threads/threads.so No symbol table info available. #13 0x00007f6c0664e9ca in start_thread () from /lib/libpthread.so.0 No symbol table info available. #14 0x00007f6c063ab6fd in clone () from /lib/libc.so.6 No symbol table info available. #15 0x0000000000000000 in ?? () No symbol table info available.
        I'm not sure what to make of it yet.
Re: stack trace from thread exit
by trwww (Priest) on Oct 25, 2010 at 19:06 UTC

    I've already tried to put logs everywhere I think of. It is as if there is a ghost between to lines in my perl script that is jumping out at me for Halloween.

    While I don't have any specific advice regarding a stack trace, I've seen weirdness like you describe here and strace has always quickly shown me what the problem is.