I was playing about with buffering and discovered this:

If I pipe a writer, which doesn't newline terminate, into a reader on linux, most often the box freezes as the swap gets sucked up. (observe with top)
I.e. power button reset job.
On my Soalris box at work (sparc) and at home (Intel) the pipeline gets kicked off, no damage done.

i tried in C also on solaris, using printf with gets and the buffer flushes occasionally even without the newline.

So maybe there is a perl feature that allows you to fill up buffers and a linux bug which allows a process to freeze the system.

./buffer_write.pl -loop |  buffer_read.pl


Here is my code:
buffer_write.pl
#!/bin/perl -s $main::size ||= 10_000; $count; sub do_write { $buf = chr int(rand(25)+65); $message = $buf x $size; $message .= "\n" if $line;; print "$message"; $count += length $message; warn "$count bytes\n"; } while ($loop || <>) { do_write; }

buffer_read.pl
#!/bin/perl -n print length($_), "\n"; print;

Replies are listed 'Best First'.
Re: who's bug is it anyway? (how to bring a linux box to it's knees)
by rhesa (Vicar) on Mar 28, 2007 at 13:31 UTC
    I don't have an answer for you right now, but consider setting an ulimit -v 100000 before testing. Instead of saturating your swap, you'll get an Out of memory! error. That way you'll see the problem sooner, and your system will remain responsive.
Re: who's bug is it anyway? (how to bring a linux box to it's knees)
by graff (Chancellor) on Mar 29, 2007 at 01:36 UTC
    rhesa's advice is good, I think, but apart from that...

    If you know your "buffer_read" thingie is going to be getting data of arbitrary (potentially extreme) length with no line terminations, you should be using the "read()" or "sysread()" function, not the diamond operator (which in your case is implied by the "-n" option). Pick a buffer size that suits your taste and "memory budget", and just read that many bytes at a time.

    (There's also a way to set $/ (input record separator) to a numeric value -- e.g.  $/ = \8192; -- so that the diamond operator just reads a fixed number of bytes on each iteration.)