Skip Menu |

This queue is for tickets about the threads CPAN distribution.

Report information
The Basics
Id: 85140
Status: resolved
Priority: 0/
Queue: threads

People
Owner: Nobody in particular
Requestors: vega.james [...] gmail.com
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 1.86
Fixed in: 1.87



Subject: Deadlock occurs if a joinable thread is sent a signal
If a thread has already finished running when a signal is sent to it, then the Perl process will deadlock at some point after that. If the thread exited normally, then the $thr->join call is where the deadlock happens, otherwise it seems to happen when the Perl process exits. I've only seen this on Linux systems so far. On Windows, the script runs to completion.
Subject: test.pl
use strict; use warnings; use threads; $| = 1; my $thr = threads->create(sub { $SIG{KILL} = sub { print "I've been killed!\n"; threads->exit(); }; print "Simple thread\n"; $ARGV[0] ? return 1 : die "Bam!"; }); print "Waiting for thread to finish...\n"; until ($thr->is_joinable()) { threads->yield(); } print "Killing thread\n"; $thr->kill('SIGKILL'); print "Joining...\n"; $thr->join(); if (my $err = $thr->error()) { print "Crap: $err\n"; } print "Done!\n";
From: James McCoy
Below are the problematic code paths according to helgrind $ valgrind --tool=helgrind debugperl threads.pl ==14933== Helgrind, a thread error detector ==14933== Copyright (C) 2007-2012, and GNU GPL'd, by OpenWorks LLP et al. ==14933== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==14933== Command: debugperl threads.pl ==14933== Waiting for thread to finish... Simple thread Thread 1 terminated abnormally: Bam! at threads.pl line 12. Killing thread Joining... Crap: Bam! at threads.pl line 12. Done! I've been killed! ==14933== ---Thread-Announcement------------------------------------------ ==14933== ==14933== Thread #1 is the program's root thread ==14933== ==14933== ---------------------------------------------------------------- ==14933== ==14933== Thread #1: Attempt to re-lock a non-recursive lock I already hold ==14933== at 0x4C2ED81: pthread_mutex_lock (hg_intercepts.c:484) ==14933== by 0x6270FA6: XS_threads_set_thread_exit_only (threads.xs:1658) ==14933== by 0x4F1212: Perl_pp_entersub (pp_hot.c:3046) ==14933== by 0x4B4517: Perl_runops_debug (dump.c:2266) ==14933== by 0x43D7BC: Perl_call_sv (perl.c:2647) ==14933== by 0x4CBD83: Perl_sighandler (mg.c:3113) ==14933== by 0x4C40BB: Perl_despatch_signals (mg.c:1491) ==14933== by 0x47B072: Perl_cv_undef (pad.c:302) ==14933== by 0x501E3A: Perl_sv_clear (sv.c:6114) ==14933== by 0x502C50: Perl_sv_free2 (sv.c:6474) ==14933== by 0x47B5FE: Perl_cv_undef (pad.c:351) ==14933== by 0x501E3A: Perl_sv_clear (sv.c:6114) ==14933== Lock was previously acquired ==14933== at 0x4C2EEC6: pthread_mutex_lock (hg_intercepts.c:495) ==14933== by 0x626FEE6: S_ithread_free (threads.xs:276) ==14933== by 0x627001C: ithread_mg_free (threads.xs:371) ==14933== by 0x503430: S_sv_unmagicext_flags (sv.c:5437) ==14933== by 0x626FBDA: XS_threads_DESTROY (threads.xs:1441) ==14933== by 0x4F1212: Perl_pp_entersub (pp_hot.c:3046) ==14933== by 0x43DAF5: Perl_call_sv (perl.c:2647) ==14933== by 0x5020A2: Perl_sv_clear (sv.c:6342) ==14933== by 0x502C50: Perl_sv_free2 (sv.c:6474) ==14933== by 0x55F98F: Perl_leave_scope (scope.c:900) ==14933== by 0x4EB78E: Perl_pp_leave (pp_hot.c:1929) ==14933== by 0x4B4517: Perl_runops_debug (dump.c:2266) ==14933== zsh: killed valgrind --tool=helgrind debugperl threads.pl $ valgrind --tool=helgrind debugperl threads.pl 1 ==15043== Helgrind, a thread error detector ==15043== Copyright (C) 2007-2012, and GNU GPL'd, by OpenWorks LLP et al. ==15043== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==15043== Command: debugperl threads.pl 1 ==15043== Waiting for thread to finish... Simple thread Killing thread Joining... I've been killed! ==15043== ---Thread-Announcement------------------------------------------ ==15043== ==15043== Thread #1 is the program's root thread ==15043== ==15043== ---------------------------------------------------------------- ==15043== ==15043== Thread #1: Attempt to re-lock a non-recursive lock I already hold ==15043== at 0x4C2ED81: pthread_mutex_lock (hg_intercepts.c:484) ==15043== by 0x6270FA6: XS_threads_set_thread_exit_only (threads.xs:1658) ==15043== by 0x4F1212: Perl_pp_entersub (pp_hot.c:3046) ==15043== by 0x4B4517: Perl_runops_debug (dump.c:2266) ==15043== by 0x43D7BC: Perl_call_sv (perl.c:2647) ==15043== by 0x4CBD83: Perl_sighandler (mg.c:3113) ==15043== by 0x4C40BB: Perl_despatch_signals (mg.c:1491) ==15043== by 0x47B072: Perl_cv_undef (pad.c:302) ==15043== by 0x501E3A: Perl_sv_clear (sv.c:6114) ==15043== by 0x502C50: Perl_sv_free2 (sv.c:6474) ==15043== by 0x47B5FE: Perl_cv_undef (pad.c:351) ==15043== by 0x501E3A: Perl_sv_clear (sv.c:6114) ==15043== Lock was previously acquired ==15043== at 0x4C2EEC6: pthread_mutex_lock (hg_intercepts.c:495) ==15043== by 0x627181C: XS_threads_join (threads.xs:1257) ==15043== by 0x4F1212: Perl_pp_entersub (pp_hot.c:3046) ==15043== by 0x4B4517: Perl_runops_debug (dump.c:2266) ==15043== by 0x4452DD: perl_run (perl.c:2350) ==15043== by 0x41E0A6: main (perlmain.c:120) ==15043== zsh: killed valgrind --tool=helgrind debugperl threads.pl 1
Fixed in v1.87 which is now available on CPAN. The fix is to ignore signals sent to threads that have finished running.