Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Segfaults with threading

Status
Not open for further replies.

rottmanja

Programmer
Aug 5, 2008
17
US
I am working on a perl app that uses multiple threads to handle multiple instances of the same sub routine. During testing, I have run into an issue with segfaults after the first thread is created and the sub routines have started to process. During the creation of the second thread is where I run into the segfault.

Any help with this is greatly appreciated. It is frustrating as hell.

Here is the code that I use to create the threads.

use Lib::pLSInstance;
use Lib::pLSParse qw(parseMain);
use Lib::Daemon;
use Data::Dumper;
use strict;
use threads;


#Lib::Daemon::daemonize();


my @thisVar = Lib::pLSInstance::getInstances();

for(my $i = 0; $i < @thisVar; $i++){
my $thr1 = threads->new(\&threadTest, $thisVar[$i][2],$thisVar[$i][1] )->join();
}





sub threadTest{
print "Child Thread $_[0] \n";
print "********************************************************************************\n";
my @thatVar = parseMain($_[0],$_[1]);
#print Dumper(@thatVar);
}

And here is what I get with a stack trace after the first thread has been started.


) = 0
stat64("/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0x9d51270) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/5.8.8/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/5.8.7/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/5.8.6/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/5.8.5/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/5.8.8/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/5.8.7/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/5.8.6/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/5.8.5/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/site_perl/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/5.8.7/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/5.8.6/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/5.8.5/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/5.8.8/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/5.8.7/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/5.8.6/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/5.8.5/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/vendor_perl/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/i386-linux-thread-multi/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("/usr/lib/perl5/5.8.8/auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
stat64("./auto/DBI/DESTROY.al", 0xbf91fb6c) = -1 ENOENT (No such file or directory)
close(3) = 0
munmap(0xb7cba000, 135168) = 0
ioctl(0, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
_llseek(0, 0, 0xbf91ff20, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(1, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
_llseek(1, 0, 0xbf91ff20, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(2, SNDCTL_TMR_TIMEBASE or TCGETS, {B38400 opost isig icanon echo ...}) = 0
_llseek(2, 0, 0xbf91ff20, SEEK_CUR) = -1 ESPIPE (Illegal seek)
ioctl(6, SNDCTL_TMR_TIMEBASE or TCGETS, 0xbf91fef8) = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(6, 0, [6019], SEEK_CUR) = 0
mmap2(NULL, 528384, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7238000
munmap(0xb7238000, 528384) = 0
clone(Child Thread HS_INT2_BASE
********************************************************************************
child_stack=0xb7cb94b4, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0xb7cb9bd8, {entry_number:6, base_addr:0xb7cb9b90, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}, child_tidptr=0xb7cb9bd8) = 4146
futex(0xb7cb9bd8, FUTEX_WAIT, 4146, NULL <unfinished ...>
+++ killed by SIGSEGV +++


 
I don't see why it would segfault, but I did notice something you're not doing right:

Code:
my $thr1 = threads->new(\&threadTest, $thisVar[$i][2],$thisVar[$i][1] )->join();

The join() method on threads will block execution until the thread you're joining has finished and stopped execution. So instead of your threads running in parallel, you're simply spawning a single thread and waiting for it to finish before iterating through your loop and spawning thread #2.

A better way of dealing with threads would be this:

Code:
use threads;

# spawn all 20 threads and let them run in parallel
my @thr = ();
for (my $i = 0; $i < 10; $i++) {
   print "Spawning thread number $i\n";
   $thr[$i] = threads->new (\&threadcode, $i);
}

# start rejoining the threads
for (my $i = 0; $i < 10; $i++) {
   print "Joining thread $i\n";
   $thr[$i]->join();
   print "\tThread $i joined back with the parent\n";
}

sub threadcode {
   my $id = shift;

   print "-->Thread $id has started<--\n";

   # sleep $id seconds
   sleep ($id);

   # return to end execution
   print "-->Thread $id is ending<--\n";
   return 1;
}

That should spawn off 10 threads pretty rapidly and each thread will sleep one second longer than the previous one. Here's my output:

Code:
[kirsle@eclipse ~]$ perl threads.pl 
Spawning thread number 0
Spawning thread number 1
-->Thread 0 has started<--
-->Thread 0 is ending<--
-->Thread 1 has started<--
Spawning thread number 2
Spawning thread number 3
-->Thread 2 has started<--
Spawning thread number 4
-->Thread 3 has started<--
Spawning thread number 5
-->Thread 4 has started<--
Spawning thread number 6
-->Thread 5 has started<--
Spawning thread number 7
-->Thread 6 has started<--
Spawning thread number 8
-->Thread 7 has started<--
Spawning thread number 9
-->Thread 9 has started<--
Joining thread 0
	Thread 0 joined back with the parent
Joining thread 1
-->Thread 8 has started<--
-->Thread 1 is ending<--
	Thread 1 joined back with the parent
Joining thread 2
-->Thread 2 is ending<--
	Thread 2 joined back with the parent
Joining thread 3
-->Thread 3 is ending<--
	Thread 3 joined back with the parent
Joining thread 4
-->Thread 4 is ending<--
	Thread 4 joined back with the parent
Joining thread 5
-->Thread 5 is ending<--
	Thread 5 joined back with the parent
Joining thread 6
-->Thread 6 is ending<--
	Thread 6 joined back with the parent
Joining thread 7
-->Thread 7 is ending<--
	Thread 7 joined back with the parent
Joining thread 8
-->Thread 8 is ending<--
	Thread 8 joined back with the parent
Joining thread 9
-->Thread 9 is ending<--
	Thread 9 joined back with the parent

Anyway, try making a simpler threading test. If your Perl segfaults then, you might just have a faulty installation of Perl and/or threads.

Also, keep in mind that some modules are not "thread-safe". IIRC there's a section on the threads documentation that talks about what thread-safe means.

-------------
Cuvou.com | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b";print$i++%2?"/":"_";goto x;'
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top