[comp.unix.questions] How do you handle while

ARaman@massey.ac.nz (A.V. Raman) (07/11/90)

Is there any way to kill all instances of a process that has the
following piece of code in it without having to bring the system down?

   while (1)
      fork();

I guess it should be possible to do something like temporarily
reducing the user's process limit to 0 and raising it back up
later; but I'm not sure how to go about it.

Any help (by email) would be appreciated.

Thanks.

- & (Anand)

peter@aucs.uucp (Peter Steele) (07/11/90)

ARaman@massey.ac.nz (A.V. Raman) writes:

>Is there any way to kill all instances of a process that has the
>following piece of code in it without having to bring the system down?

>   while (1)
>      fork();

>Any help (by email) would be appreciated.

I think a summary of responses to this question would be appreciated.
We've had students do this on many occasions on our Sun. It's a pretty
quick way to crash the system and I for one would like to know if there
are any feasible solutions.

-- 
Peter Steele, Microcomputer Applications Analyst
Acadia University, Wolfville, NS, Canada B0P1X0 (902)542-2201x121
UUCP: {uunet|watmath|utai|garfield}!cs.dal.ca!aucs!Peter
BITNET: Peter@Acadia  Internet: Peter@AcadiaU.CA

jrw@mtune.ATT.COM (Jim Webb) (07/11/90)

In article <841@massey.ac.nz>, ARaman@massey.ac.nz (A.V. Raman) writes:
> Is there any way to kill all instances of a process that has the
> following piece of code in it without having to bring the system down?
> 
>    while (1)
>       fork();

Under System V, running "kill -9 -1" will send the kill to all processes
belonging to the invoking user.  So, to stop the above, you could do that
as the user (if s/he has any processes left) or by becoming root and then
entering:

		su pest -c "kill -9 -1"

if no process slots are available to the user.  Obviously, this kills
everything that user is running, not just the above wonderfulness.

Have fun.

-- 
Jim Webb                "Out of Phase -- Get Help"               att!mtune!jrw
                  "I'm bored with this....Let's Dance!"

rhys@batserver.cs.uq.oz.au (Rhys Weatherley) (07/12/90)

peter@aucs.uucp (Peter Steele) writes:

>ARaman@massey.ac.nz (A.V. Raman) writes:

>>Is there any way to kill all instances of a process that has the
>>following piece of code in it without having to bring the system down?

>>   while (1)
>>      fork();

>>Any help (by email) would be appreciated.

>I think a summary of responses to this question would be appreciated.
>We've had students do this on many occasions on our Sun.

I would also be interested in a summary, but how about this one:

	while (!fork ())
	  {
	    /* some non-important code */
	  }
	/* some "clean-up" code */
	exit (0);

This will create a round-robin of processes, where each process spawns
a child, and then dies (fork() returns 0 in the child process).  Extremely 
difficult to kill these ones, because by the time you have a process-id 
to kill, that process doesn't exist usually anymore!  This is an 
over-simplification of the code to produce this effect, but both examples 
show the danger of using fork(), when you don't really know what you're doing!  

Personally I prefer the idea of having some sort of library 'spawn' function 
which takes a program name and arguments (similar to exec, without overwriting
the current process), and takes care of all the details for you when you want 
to start up a new program as a child process, allowing the experts to deal 
with fork() and its friends.  (This has no doubt been covered before :-).

Rhys.

+===============================+==============================+
||  Rhys Weatherley             |  University of Queensland,  ||
||  rhys@batserver.cs.uq.oz.au  |  Australia.  G'day!!        ||
+===============================+==============================+

mpl@pegasus.ATT.COM (Michael P. Lindner) (07/13/90)

In article <4261@uqcspe.cs.uq.oz.au> rhys@batserver.cs.uq.oz.au writes:
>peter@aucs.uucp (Peter Steele) writes:
>>ARaman@massey.ac.nz (A.V. Raman) writes:
>>>Is there any way to kill all instances of a process that has the
>>>following piece of code in it without having to bring the system down?
>
>>>   while (1)
>>>      fork();
>
>>>Any help (by email) would be appreciated.
>
>>I think a summary of responses to this question would be appreciated.
>>We've had students do this on many occasions on our Sun.
	deleted stuff

How about something like:

main(argc, argv)
int	argc;
char	*argv[];
{
	setuid(atoi(argv[1]));
	kill(-1, 9);
}

With appropriate checks for validity of arguments and return codes, of
course.  Man page for kill(2)... "if pid is -1, and the effective user ID
of the sender is not super-user, sig will be sent to all processes excluding
proc0 and proc1 whose real user ID is equal to the effective user ID of
the sender.  When the above program is run as super-user, with the offender's
numerical user ID as its argument, it makes its user ID the same as the
offender's and kills all processes belonging to that user.  Not sure if
this'll work on non-System V machines.

Mike Lindner
attmail!mplindner

rli@buster.irby.com (Buster Irby) (07/13/90)

rhys@batserver.cs.uq.oz.au (Rhys Weatherley) writes:

>peter@aucs.uucp (Peter Steele) writes:

>>ARaman@massey.ac.nz (A.V. Raman) writes:

>>>Is there any way to kill all instances of a process that has the
>>>following piece of code in it without having to bring the system down?

>>>   while (1)
>>>      fork();

>>>Any help (by email) would be appreciated.

>>I think a summary of responses to this question would be appreciated.
>>We've had students do this on many occasions on our Sun.

>I would also be interested in a summary, but how about this one:

>	while (!fork ())
>	  {
>	    /* some non-important code */
>	  }
>	/* some "clean-up" code */
>	exit (0);

I don't know about Sun's, but on System V you can use the fuser command
to kill all processes attacked to the tty or any other common resource
which is shared by all of the children.  It can be used to effectively
perform a kill process group operation on all processes attatched to a
specific tty as follows:

$ fuser -k /dev/tty?? 

P.S. You must be root to execute this as it sends the SIGKILL signal to
the processes.
-- 
Buster Irby  buster!rli

dt@yenta.alb.nm.us (David B. Thomas) (07/13/90)

jrw@mtune.ATT.COM (Jim Webb) writes:

>In article <841@massey.ac.nz>, ARaman@massey.ac.nz (A.V. Raman) writes:
>> Is there any way to kill all instances of a process that has the
>> following piece of code in it without having to bring the system down?
>> 
>>    while (1)
>>       fork();

>Under System V, running "kill -9 -1" will send the kill to all processes
>belonging to the invoking user.  So, to stop the above, you could do that
>as the user (if s/he has any processes left) or by becoming root and then
>entering:

>		su pest -c "kill -9 -1"

>if no process slots are available to the user.  Obviously, this kills
>everything that user is running, not just the above wonderfulness.

Am I missing something?  I thought the kernel table had only so many
slots for processes on the whole system, each of which is available
to anyone.  Therefore, the nasty code would hog every last slot,
preventing the administrator's shell from forking 'su'.  And you can't
'exec' su, since then su would still fail to fork 'kill', and then you're
logged out!

Maybe unix has some saneness I haven't learned about yet to prevent this.

						David

chip@tct.uucp (Chip Salzenberg) (07/13/90)

According to ARaman@massey.ac.nz (A.V. Raman):
>Is there any way to kill all instances of a process that has the
>following piece of code in it without having to bring the system down?
>
>   while (1)
>      fork();

If they're not daemon processes, you can kill the process group they
belong to.

In addition, modern Unix versions have limits on the number of
processes that can be created by any one user.  Be sure that this
number is quite a bit smaller than the system-wide process count.
-- 
Chip, the new t.b answer man      <chip@tct.uucp>, <uunet!ateng!tct!chip>

kseshadr@quasar.intel.com (Kishore Seshadri) (07/14/90)

In article <1990Jul11.115612.2155@aucs.uucp>, peter@aucs (Peter Steele) writes:
>ARaman@massey.ac.nz (A.V. Raman) writes:
>
>>Is there any way to kill all instances of a process that has the
>>following piece of code in it without having to bring the system down?
>
>>   while (1)
>>      fork();
>
>>Any help (by email) would be appreciated.

I actually haven't had to deal with this, but wouldn't killing the login
shell of the "offender" handle the simple cases like this? Of course,
this may not work for cases where the process has detached itself from
the tty or changed its process group. You could try writing something
that does a vhangup on the offender's tty and then actually go through
the proc table looking for other processes owned by the person. This
may be pretty drastic solution, however! 

I'd be interested in hearing other ways of doing this.

Kishore
kishore@mipos3.intel.com

===============================================================================
Kishore Seshadri (Speaking only for myself) Intel Corp., Santa Clara, CA
CSNET: kseshadr@mipos3.intel.com ARPA: kseshadr%mipos3.intel.com@relay.cs.net
UUCP:{amdcad,decwrl,hplabs,oliveb,pur-ee,qantel}!intelca!mipos3!kseshadr

peter@ficc.ferranti.com (Peter da Silva) (07/14/90)

In article <1655@yenta.alb.nm.us> dt@yenta.alb.nm.us (David B. Thomas) writes:
> preventing the administrator's shell from forking 'su'.  And you can't
> 'exec' su, since then su would still fail to fork 'kill', and then you're
> logged out!

exec su -c 'exec kill -9 -1'

So the user just has to put something in their .cshrc to force the shell
to exit if they can't fork.

	set a=`echo hi`
	if (a != hi) exit
-- 
Peter da Silva.   `-_-'
+1 713 274 5180.
<peter@ficc.ferranti.com>

cpcahil@virtech.uucp (Conor P. Cahill) (07/14/90)

In article <1655@yenta.alb.nm.us> dt@yenta.alb.nm.us (David B. Thomas) writes:
>jrw@mtune.ATT.COM (Jim Webb) writes:
>
>Am I missing something?  I thought the kernel table had only so many
>slots for processes on the whole system, each of which is available
>to anyone.  Therefore, the nasty code would hog every last slot,

Unix systems have a per-user limit on the number of processes
in addition to the system wide limit.  Most systems will also
keep a normal user process form using up the last free slot in
the process table (that is left for root).

-- 
Conor P. Cahill            (703)430-9247        Virtual Technologies, Inc.,
uunet!virtech!cpcahil                           46030 Manekin Plaza, Suite 160
                                                Sterling, VA 22170 

gt0178a@prism.gatech.EDU (BURNS,JIM) (07/14/90)

in article <1655@yenta.alb.nm.us>, dt@yenta.alb.nm.us (David B. Thomas) says:
> Am I missing something?  I thought the kernel table had only so many
> slots for processes on the whole system, each of which is available
> to anyone.  

I'm not sure how other unixes do it, but under HP-UX, a Bsd derivative with
SVID certification, there are two separate parameters in the gen file (some-
thing like /etc/conf/S800 - I'm not at work) - one is maxuproc for max. no.
procs per user, and the other controls total system procs.
-- 
BURNS,JIM
Georgia Institute of Technology, Box 30178, Atlanta Georgia, 30332
uucp:	  ...!{decvax,hplabs,ncar,purdue,rutgers}!gatech!prism!gt0178a
Internet: gt0178a@prism.gatech.edu

thorinn@skinfaxe.diku.dk (Lars Henrik Mathiesen) (07/14/90)

jrw@mtune.ATT.COM (Jim Webb) writes:
>>    while (1)
>>       fork();

>Under System V, running "kill -9 -1" will send the kill to all processes
>belonging to the invoking user.  So, to stop the above, you could do that
>as the user (if s/he has any processes left) or by becoming root and then
>entering:

>		su pest -c "kill -9 -1"

There are two problems with this (at least in BSD): Firstly, su will
use the user's shell, and csh will not accept the command, I think.

More seriously, race conditions in the kernel will usually allow a few
of these processes to survive: If a process is inside the fork system
call but the new process slot hasn't been assigned yet, the kill
signal will only be posted for the parent. When the system call
completes, the parent is killed, but the child survives.

You have to repeat the call to kill, and rapidly, otherwise the user's
process limit will be reached again in milliseconds. I have had
success with code like this:

------killall.c ---------
/* Call (as root): killall numeric-uid */
main(argc, argv)
	char **argv;
{
	nice(-40);
	setuid(atoi(argv[1]));
	if (getuid() <= 0) /* Something's wrong */
		exit(1);
	while(kill(-1,9) == 0)
		/* There's someone out there, repeat */ ;
	exit(0);
}
-------------------------
Add error messages, name-to-uid translation etc. as you like. And
don't run this when you're not root (exercise: why not?).

--
Lars Mathiesen, DIKU, U of Copenhagen, Denmark      [uunet!]mcsun!diku!thorinn
Institute of Datalogy -- we're scientists, not engineers.      thorinn@diku.dk

guy@auspex.auspex.com (Guy Harris) (07/15/90)

>Under System V, running "kill -9 -1" will send the kill to all processes
>belonging to the invoking user.

As long as the invoking user isn't the super-user; to quote the SunOS
4.0.3 manual page (yes, 4.0.3 supports this in an S5-compatible
fashion, except that it doesn't deliver the signal to the sending
process; dunno why it does so in S5, it seems kind of dumb to me):

     If pid is -1 and the effective user ID of the sender is  not
     super-user, the signal is sent to all processes, except sys-
     tem processes, process 1, and the process sending  the  sig-
     nal,  whose  real  or  saved set-user ID matches the real or
     effective ID of the sender.

     If pid is -1 and the effective user  ID  of  the  sender  is
     super-user,  the signal is sent to all processes except sys-
     tem processes, process 1, and the process sending  the  sig-
     nal.

So if you become "root" and run this, you will kill just about every
process on the system....

You probably don't want to do this.

guy@auspex.auspex.com (Guy Harris) (07/15/90)

>Am I missing something?  I thought the kernel table had only so many
>slots for processes on the whole system, each of which is available
>to anyone.

Yes, you're missing something.  Modern versions of UNIX (V7 and later)
(unless some exceptionally bright person took it out of some system)
allow only the super-user to take the last slot in the process table.

If you have a "getty" running on a terminal, you should log in as "root"
on that terminal; your shell uses the same process slot as the "getty",
and the "reserved" slot probably isn't taken up yet, thus increasing the
chances that slot will be available for "kill".

Alternatively, if you have a shell where "kill" is a built-in (e.g.  the
C shell), the "kill" won't require another slot.

dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (07/15/90)

On BSD systems, at least, one way to recover from a "while(1) fork();"
situation is to log in as the offending user and execute my die/suicide
program, which in essence is:

   kill (-1, SIGTERM);	/* give each process a software termination signal */
   sleep (3);		/* and give it 3 seconds to clean up */
   kill (-1, SIGKILL);	/* then kill each process with extreme prejudice */
--
Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP:  oliveb!cirrusl!dhesi

ag@cbmvax.commodore.com (Keith Gabryelski) (07/16/90)

In article <3651@auspex.auspex.com> guy@auspex.auspex.com (Guy Harris) writes:
>If you have a "getty" running on a terminal, you should log in as "root"
>on that terminal; your shell uses the same process slot as the "getty",
>and the "reserved" slot probably isn't taken up yet, thus increasing the
>chances that slot will be available for "kill".
>
>Alternatively, if you have a shell where "kill" is a built-in (e.g.  the
>C shell), the "kill" won't require another slot.

Alternately, if kill in not a built-in, you could use:

	$ exec kill -15 -1

Risky because kill will take over the process slot and you will be
logged out but possibly useful to know.

Pax, Keith

price@chakra.unl.edu (Chad Price) (07/17/90)

In <671@mtune.ATT.COM> jrw@mtune.ATT.COM (Jim Webb) writes:

>In article <841@massey.ac.nz>, ARaman@massey.ac.nz (A.V. Raman) writes:
>> Is there any way to kill all instances of a process that has the
>> following piece of code in it without having to bring the system down?
>> 
>>    while (1)
>>       fork();

>Under System V, running "kill -9 -1" will send the kill to all processes
>belonging to the invoking user.  So, to stop the above, you could do that
>as the user (if s/he has any processes left) or by becoming root and then
>entering:

>		su pest -c "kill -9 -1"

>if no process slots are available to the user.  Obviously, this kills
>everything that user is running, not just the above wonderfulness.

>Have fun.

>-- 
>Jim Webb                "Out of Phase -- Get Help"               att!mtune!jrw
>                  "I'm bored with this....Let's Dance!"

I think that will not work (personal experience). Any process that is
doing a while(1)fork(); will drag the system down too far for this to
help. What you need to do is renice the processes down and then kill them
all. THe solution is courtesy of Rory Cejka (now at Utah) who did this
for me when I made the above mistake.  This works on Ultrix.

Use the following 2 shell-scripts (as root):


#! /bin/sh
# @(#)Renices all processes with lines from a "ps aug" that match
# @(#)the pattern given in the second argument to the priority given
# @(#)in the first argument.
#
z=`ps -aug | grep $2 | grep -v grep | grep -v csh | grep -v kill | awk '{ print $2 }'`
renice $1 $z



#! /bin/sh
# @(#)Kills all processes with lines from a "ps aug" that match
# @(#)the pattern given in the first argument.
#
z=`ps -aug | grep $1 | grep -v grep | grep -v csh | grep -v kill | awk '{ print $2 }'`
kill -9 $z


Chad Price
price@fergvax.unl.edu

leo@ehviea.ine.philips.nl (Leo de Wit) (07/17/90)

OK, for those who are still interested: yet another solution.

It has the obvious advantages it can be executed by the user himself, and
it is not system specific (most of the solutions offered needed root
privilege, or a System V environment).

I had to do this once for a shell script that invoked itself conditionally;
unfortunately the condition was always true, so I quickly ended up with all
my process slots occupied. No system manager at hand. This is how I did it:

a) Found out the offending process ids with a 'ps agx' logged in as another
user (of course, even a fork for a ps would fail).
b) Next sent all those processes a SIGSTOP; this makes them harmless,
yet they still occupy their process slots. For a C shell, this can be done
with the builtin kill. For a Bourne shell, do an exec kill -STOP on all
processes (except the login shell); this will log you out (but there's
still a free process slot).
c) Killed all the processes with an appropriate signal. Since the
'forkers' have been made inactive, you don't have to be afraid that the
free process slots will get occupied.
d) Wiped off my forehead. Done!

    Leo.

als@bohra.cpg.oz (Anthony Shipman) (07/17/90)

In article <4261@uqcspe.cs.uq.oz.au>, rhys@batserver.cs.uq.oz.au (Rhys Weatherley) writes:
> I would also be interested in a summary, but how about this one:
> 
> 	while (!fork ())
> 	  {
> 	    /* some non-important code */
> 	  }
> 	/* some "clean-up" code */
> 	exit (0);
> 
> This will create a round-robin of processes, where each process spawns
> a child, and then dies (fork() returns 0 in the child process).  Extremely 
> difficult to kill these ones, because by the time you have a process-id 
> to kill, that process doesn't exist usually anymore!  This is an 

I had this problem once. I used a little program that did a kill -9 on a pid
that was ahead of the pid sequence from the runaway program. The kill -9 was
put into an infinite loop. There was a good chance that the kill would get the
process when its pid got big enough. (There was also some chance that an
innocent process would be killed, but not much).
-- 
Anthony Shipman                               ACSnet: als@bohra.cpg.oz.au
Computer Power Group
9th Flr, 616 St. Kilda Rd.,
St. Kilda, Melbourne, Australia
D

guy@auspex.auspex.com (Guy Harris) (07/18/90)

>It has the obvious advantages it can be executed by the user himself, and
>it is not system specific (most of the solutions offered needed root
>privilege, or a System V environment).

Err, your solution requires SIGSTOP, which isn't in every UNIX
variant....

jrw@mtune.ATT.COM (Jim Webb) (07/18/90)

In article <price.648165820@chakra>, price@chakra.unl.edu (Chad Price) writes:
> In <671@mtune.ATT.COM> jrw@mtune.ATT.COM (Jim Webb) [HI MOM!] wrote:
>	[about kill -9 -1 killing all processes belonging to a user]

> I think that will not work (personal experience). Any process that is
> doing a while(1)fork(); will drag the system down too far for this to
> help. What you need to do is renice the processes down and then kill them
> all. THe solution is courtesy of Rory Cejka (now at Utah) who did this
> for me when I made the above mistake.  This works on Ultrix.

A couple of comments.

Number one, System V (at least before SVR4) doesn't have a renice command
as a standard command, and that's what OS I based my answer on.  Granted,
it would be easy enough to write (less than 100 lines of code) but that's
another story.

Number two, If a normal user, eg not root, runs "while(1)fork();" it will
just run up to the max number of processes allowed per user and then fail
forever.   During this time, the machine will be slow, granted, but I can
not see how a _single kill system call_ will be less effective at killing
the processes than running at least 2 shells, 8 greps (check out egrep!),
2 awks, 2 ps's, 1 renice, and then finally multiple kill system calls:

> #! /bin/sh
> # @(#)Renices all processes with lines from a "ps aug" that match
> # @(#)the pattern given in the second argument to the priority given
> # @(#)in the first argument.
> #
> z=`ps -aug | grep $2 | grep -v grep | grep -v csh | grep -v kill | awk '{ print $2 }'`
> renice $1 $z
> 
> #! /bin/sh
> # @(#)Kills all processes with lines from a "ps aug" that match
> # @(#)the pattern given in the first argument.
> #
> z=`ps -aug | grep $1 | grep -v grep | grep -v csh | grep -v kill | awk '{ print $2 }'`
> kill -9 $z
> 
> Chad Price
> price@fergvax.unl.edu

If anything, bag the second shell script and add a "kill -9 $z" to the end
of the first one :-)

L
a
t
e
r....

-- 
Jim Webb                "Out of Phase -- Get Help"               att!mtune!jrw
                  "I'm bored with this....Let's Dance!"

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (07/18/90)

In article <2036@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes:
> kill (-1, SIGTERM);	/* give each process a software termination signal */
> sleep (3);		/* and give it 3 seconds to clean up */

If the processes aren't malicious, 3 seconds probably isn't enough---
remember that the system is heavily loaded. If the processes are
malicious, sleep() renders your solution useless. At least split the
program into two, the first with a sleep(30) and the second with no
pause.

---Dan

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (07/18/90)

In article <price.648165820@chakra> price@chakra.unl.edu (Chad Price) writes:
> What you need to do is renice the processes down and then kill them
> all.

Your solutions are based on very slow shell scripts, so sufficiently
clever malicious processes can dodge them.

---Dan

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (07/19/90)

In article <21028:Jul1807:45:0590@kramden.acf.nyu.edu> brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
: In article <price.648165820@chakra> price@chakra.unl.edu (Chad Price) writes:
: > What you need to do is renice the processes down and then kill them
: > all.
: 
: Your solutions are based on very slow shell scripts, so sufficiently
: clever malicious processes can dodge them.

What's going on here is Core Wars in pid-space, almost.  It'd be more like
it if the enemy process could kill you too.  Give them a sporting chance,
and all that...

Larry Wall
lwall@jpl-devvax.jpl.nasa.gov

karish@mindcrf.UUCP (07/19/90)

In article <21028:Jul1807:45:0590@kramden.acf.nyu.edu>
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) writes:
>In article <price.648165820@chakra> price@chakra.unl.edu (Chad Price) writes:
>> What you need to do is renice the processes down and then kill them
>> all.
>
>Your solutions are based on very slow shell scripts, so sufficiently
>clever malicious processes can dodge them.

If you're dealing with a malicious process, go ahead and reboot the
machine.  Then hang the perpetrator by his/her toes in your users'
terminal room, as an example.

-- 

	Chuck Karish		karish@mindcraft.com
	Mindcraft, Inc.		(415) 323-9000		

tana@ee.sophia.ac.jp (Yoshiyuki Tanaka) (07/23/90)

I often use the following script to kill processes by its names. It's
stupid (kills itself) and dangerous (kills any process which includes
the argument as its name), but it works to kill zombies if run a
couple of times. I advise not to use it as root.

#!/bin/sh -f
pid=`ps -e | egrep $1 | awk '{print $1}'` 
echo KILLING $pid
kill -9 $pid >/dev/null 2>&1

----------------------------------------------------------------------------
				Yoshiyuki Tanaka
				Sophia University, Tokyo Japan.
				Dept of Electrical & Electronic Enginerring
				Deiters Laboratory.
				Email: tana@bob.ee.sophia.ac.jp
----------------------------------------------------------------------------

ashley@hoss.unl.edu (David Ashley) (07/24/90)

In <price.648165820@chakra> price@chakra.unl.edu (Chad Price) writes:

>In <671@mtune.ATT.COM> jrw@mtune.ATT.COM (Jim Webb) writes:

>>In article <841@massey.ac.nz>, ARaman@massey.ac.nz (A.V. Raman) writes:
>>> Is there any way to kill all instances of a process that has the
>>> following piece of code in it without having to bring the system down?
>>> 
>>>    while (1)
>>>       fork();

>>Under System V, running "kill -9 -1" will send the kill to all processes
>>belonging to the invoking user.  So, to stop the above, you could do that
>>as the user (if s/he has any processes left) or by becoming root and then
>>entering:

>>		su pest -c "kill -9 -1"

>>if no process slots are available to the user.  Obviously, this kills
>>everything that user is running, not just the above wonderfulness.

>>Have fun.

>>-- 
>>Jim Webb                "Out of Phase -- Get Help"               att!mtune!jrw
>>                  "I'm bored with this....Let's Dance!"

>I think that will not work (personal experience). Any process that is
>doing a while(1)fork(); will drag the system down too far for this to
>help. What you need to do is renice the processes down and then kill them
>all. THe solution is courtesy of Rory Cejka (now at Utah) who did this
>for me when I made the above mistake.  This works on Ultrix.

>Use the following 2 shell-scripts (as root):


>#! /bin/sh
># @(#)Renices all processes with lines from a "ps aug" that match
># @(#)the pattern given in the second argument to the priority given
># @(#)in the first argument.
>#
>z=`ps -aug | grep $2 | grep -v grep | grep -v csh | grep -v kill | awk '{ print $2 }'`
>renice $1 $z



>#! /bin/sh
># @(#)Kills all processes with lines from a "ps aug" that match
># @(#)the pattern given in the first argument.
>#
>z=`ps -aug | grep $1 | grep -v grep | grep -v csh | grep -v kill | awk '{ print $2 }'`
>kill -9 $z


>Chad Price
>price@fergvax.unl.edu

This also will not work in all cases due to the following reason.
In a sense a race condition can still arise, even with niced processes and
the killing job renice to -19.

The better solution that we have found is as follows:

	Send a stop signal to all processes involved in the while(1) fork();
	Then send the kill signal to the processes.
	Remark: no renicing is required.


David Ashley (and Rory Cejka)
email: ashley@hoss.unl.edu
       (cejka@cs.utah.edu)

fritchie@sachiko.acc.stolaf.edu (Scott Fritchie; ACC @ St. Olaf College) (07/30/90)

In article <841@massey.ac.nz> ARaman@massey.ac.nz (A.V. Raman) writes:

   Is there any way to kill all instances of a process that has the
   following piece of code in it without having to bring the system down?

      while (1)
	 fork();

For BSD, if you've got a super-user shell handy, you can send SIGSTOP
signals to all of the offending processes using something along these
lines:

	ps tXX | grep -v PID | awk '{print $1}' | xargs kill -STOP

Once the forking (:-) processes have been stopped, they can be
terminated at leisure by hand or using a variation of the above
pipeline.

						-Scott
---
       Scott Fritchie, 4810 Underwood Ave., Omaha, NE  68132-2420  USA
     fritchie@acc.stolaf.edu   ..!umn-cs!stolaf!fritchie  (402) 553-4084
   "Yeah, boss, I'll be in late today.  UNIX refuses to boot on my Ford."