From owner-freebsd-hackers Wed Jun 10 19:41:39 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id TAA25507 for freebsd-hackers-outgoing; Wed, 10 Jun 1998 19:41:39 -0700 (PDT) (envelope-from owner-freebsd-hackers@FreeBSD.ORG) Received: from couatl.uchicago.edu (couatl.uchicago.edu [128.135.21.64]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id TAA25421 for ; Wed, 10 Jun 1998 19:41:10 -0700 (PDT) (envelope-from sfarrell@couatl.uchicago.edu) Received: (from sfarrell@localhost) by couatl.uchicago.edu (8.9.0/8.9.0) id VAA12135; Wed, 10 Jun 1998 21:41:08 -0500 (CDT) To: freebsd hackers Subject: perl forking causes panic in 2.2.6-stable From: sfarrell@farrell.org Mime-Version: 1.0 (generated by tm-edit 7.108) Content-Type: text/plain; charset=US-ASCII Date: 10 Jun 1998 21:41:08 -0500 Message-ID: <87bts0lkxn.fsf@couatl.uchicago.edu> Lines: 105 X-Mailer: Gnus v5.6.9/XEmacs 20.4 - "Emerald" Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG tom christiansen posted a nifty prime number generator script that uses forking to approximate threads [attached below]. i decided it was a little bit boring at only find primes under 1000, so i upped the number to 5000. unfortunately this panics my machine! the panic is get_pv_entry: cannot get a pv_entry_t. i tried a less creative fork bomb with sh and noticed that it gives "cannot fork", causes significant denial of service, but can be killed and does not panic. sparc/solaris gives an error: can't pipe: too many open files..., but no panic. FreeBSD 2.2.6-STABLE #0: Mon Jun 8 21:58:37 CDT 1998 ------------------------------------------------------------------- #!/usr/bin/perl # prime-fork: use sugalskd's thread algorithm # but with real processes. sub main; sub check_num; sub forksub(&); sub queue; sub enqueue(*$); sub dequeue(*); use strict; main(); exit; sub main { pipe(UPSTREAM, DOWNSTREAM); my($head,$tail) = queue(); my $kid = forksub { close($tail); check_num($head, 2) }; close $head; for (my $i = 3; $i <= 5000; $i++) { enqueue($tail, $i); } close $tail; waitpid($kid,0); } sub check_num { my ($stream, $cur_prime) = @_; my ($spawned, $num); my($head, $tail) = queue(); while ($num = dequeue($stream) ) { next unless $num % $cur_prime; if ($spawned) { enqueue($tail, $num); next; } print "Found prime $num\n"; $spawned = forksub { close($tail); check_num($head, $num) }; close $head; } close($head) unless $spawned; close($tail); waitpid($spawned,0) if $spawned; exit; } sub forksub(&) { my $coderef = $_[0]; my $pid = fork(); die "cannot fork: $!" unless defined $pid; return $pid if $pid; goto &$coderef; # don't need no stinkin' stack frames } sub queue { local(*READER, *WRITER); pipe(READER, WRITER) || die "can't pipe: $!"; return (*READER, *WRITER); } sub enqueue(*$) { my ($stream, $n) = @_; syswrite($stream, pack("L", $n), 4); # XXX: errno } sub dequeue(*) { my ($stream) = @_; my $n; sysread($stream, $n, 4) == 4 || return; unpack("L", $n); } -- Steve Farrell To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message