public inbox for frysk-cvs@sourceware.org
help / color / mirror / Atom feed
* [SCM]  master: Add ability to kill a process using its PID.
@ 2008-03-13 15:53 rmoseley
  0 siblings, 0 replies; only message in thread
From: rmoseley @ 2008-03-13 15:53 UTC (permalink / raw)
  To: frysk-cvs

The branch, master has been updated
       via  115cd21f235b29fe70e9da77c8a6298aab692569 (commit)
      from  f7bc2b759574fce3842b3b60fe473a9bb8b10431 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 115cd21f235b29fe70e9da77c8a6298aab692569
Author: Rick Moseley <rmoseley@localhost.localdomain>
Date:   Thu Mar 13 10:52:46 2008 -0500

    Add ability to kill a process using its PID.
    
    * KillCommand.java: Add ability to kill by PID.
    * TestKillCommand.java: Add test for above.

-----------------------------------------------------------------------

Summary of changes:
 frysk-core/frysk/hpd/ChangeLog            |    3 +
 frysk-core/frysk/hpd/KillCommand.java     |  112 ++++++++++++++++++++---------
 frysk-core/frysk/hpd/TestKillCommand.java |   69 ++++++++++++++----
 3 files changed, 138 insertions(+), 46 deletions(-)

First 500 lines of diff:
diff --git a/frysk-core/frysk/hpd/ChangeLog b/frysk-core/frysk/hpd/ChangeLog
index d4a47a1..406d23d 100644
--- a/frysk-core/frysk/hpd/ChangeLog
+++ b/frysk-core/frysk/hpd/ChangeLog
@@ -2,6 +2,9 @@
 
 	* CLI.java: Synchronize message adding when type specified.
 	* LoadCommand.java: Use message logger instead of direct print.
+	
+	* KillCommand.java: Add ability to kill by PID.
+	* TestKillCommand.java: Add test for above.
 
 2008-03-10  Mark Wielaard  <mwielaard@redhat.com>
 
diff --git a/frysk-core/frysk/hpd/KillCommand.java b/frysk-core/frysk/hpd/KillCommand.java
index 13f9bfd..26f11b2 100644
--- a/frysk-core/frysk/hpd/KillCommand.java
+++ b/frysk-core/frysk/hpd/KillCommand.java
@@ -1,6 +1,6 @@
 // This file is part of the program FRYSK.
 //
-// Copyright 2007, 2008, Red Hat Inc.
+// Copyright 2007, 2008 Red Hat Inc.
 //
 // FRYSK is free software; you can redistribute it and/or modify it
 // under the terms of the GNU General Public License as published by
@@ -39,11 +39,9 @@
 
 package frysk.hpd;
 
-//import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.Map;
-import java.util.TreeMap;
 import frysk.proc.Proc;
 import frysk.proc.Task;
 import java.util.List;
@@ -53,54 +51,102 @@ import java.util.List;
  */
 
 public class KillCommand extends ParameterizedCommand {
-    private static String full = "kill the processes that are currently in " +
-    	"the current target set.  The processes are then reloaded and then " +
-    	"ready to be run again.";
+    private static String full = "kill [PID]\n" + 
+	"kill the processes that are currently in " +
+    	"the current target set or kill a specific PID.  If kill is run " +
+    	"without parameters, all processes in the current target set are " +
+    	"killed and then reloaded and are then ready to be run again.";
+    
+    Map saveProcs = new HashMap();
 
     KillCommand() {
-	super("kill the current targetset", "kill", full);
+	super("kill the current targetset or kill a specific PID", "kill", full);
     }
 
     public void interpret(CLI cli, Input cmd, Object options) {
 	
-	Map saveProcs = new HashMap();
-	saveProcs = new TreeMap();
+	if (cmd.size() > 2)
+	    throw new InvalidCommandException("Too many parameters");
+	    
+	switch (cmd.size()) {
+	
+	case 0:
+	
+	    killProc(-1, cli);
+	    cli.outWriter.flush();
+	    
+	    synchronized (cli) {
+		// Clear the running procs set
+		cli.runningProcs.clear();
+		// Clear the stepping engine structures
+		cli.steppingEngine.clear();
+		// Add back in the stepping observer for cli
+		cli.steppingEngine.addObserver(cli.steppingObserver);
+	    }
+	    // Now loop through and re-load all of the killed procs
+	    Iterator bar = saveProcs.keySet().iterator();
+	    while (bar.hasNext()) {
+		Integer procId = (Integer) bar.next();
+		String cmdline = (String) saveProcs.get(procId);
+		cli.taskID = procId.intValue();
+		cli.execCommand("load " + cmdline + "\n");
+	    }
+	    cli.taskID = -1;
+	    break;
+	
+	// This is the case where a PID was entered
+	case 1:
+	    int pid;
+	    try {
+		pid = Integer.parseInt(cmd.parameter(0));
+	    } catch (NumberFormatException e) {
+		cli.addMessage("PID entered is not an integer", Message.TYPE_ERROR);
+		return;
+	    }
+	    if (!killProc(pid, cli))
+		cli.addMessage("PID " + pid + " could not be found", Message.TYPE_ERROR);
+	}
+    }
+	
+    /**
+     * killProc will kill all Procs or just the Proc specified by the PID
+     * passed to it.
+     * 
+     * @param pid
+     *                is an int containing the PID that should be killed, if
+     *                pid < 0, kill all the PIDs frysk in targetset, else just
+     *                kill the process of the specified PID.
+     * @param cli
+     *                is the current command line interface object
+     */
+	
+    boolean killProc(int pid, CLI cli) {
 	int procPID = 0;
 	Iterator foo = cli.targetset.getTaskData();
 	while (foo.hasNext()) {
 	    TaskData taskData = (TaskData) foo.next();
 	    Task task = taskData.getTask();
 	    Proc proc = task.getProc();
-	    if (proc.getPid() != procPID) {
-		cli.outWriter.println("Killing process " + proc.getPid()
-				      + " that was created from "
-				      + proc.getExe());
+	    if ((proc.getPid() != procPID && pid < 0) ||
+		    proc.getPid() == pid) {
+		cli.addMessage("Killing process " + proc.getPid()
+			+ " that was created from " + proc.getExe(),
+			Message.TYPE_NORMAL);
+		cli.outWriter.flush();
 		// Save the procs we are killing so we can re-load them later
-		saveProcs.put(new Integer(taskData.getParentID()),
-			      proc.getExe());
+		saveProcs.put(new Integer(taskData.getParentID()), proc
+			.getExe());
 		procPID = proc.getPid();
 		// Now, call the Proc object to kill off the executable(s)
 		proc.requestKill();
+		if ((pid > 0))
+		    return true;
 	    }
 	}
-	
-	synchronized (cli) {
-	    // Clear the running procs set
-	    cli.runningProcs.clear();
-	    // Clear the stepping engine structures
-	    cli.steppingEngine.clear();
-	    // Add back in the stepping observer for cli
-	    cli.steppingEngine.addObserver(cli.steppingObserver);
-	}
-	// Now loop through and re-load all of the killed procs
-	Iterator bar = saveProcs.keySet().iterator();
-	while (bar.hasNext()) {
-	    Integer procId = (Integer) bar.next();
-	    String cmdline = (String) saveProcs.get(procId);
-	    cli.taskID = procId.intValue();
-	    cli.execCommand("load " + cmdline + "\n");
-	}
-	cli.taskID = -1;
+	// If we got to here and pid > 0 then we did not find that PID
+	if (pid > 0)
+	    return false;
+	return true;
     }
 
     int completer(CLI cli, Input input, int cursor, List completions) {
diff --git a/frysk-core/frysk/hpd/TestKillCommand.java b/frysk-core/frysk/hpd/TestKillCommand.java
index 5c1eedf..13ccecd 100644
--- a/frysk-core/frysk/hpd/TestKillCommand.java
+++ b/frysk-core/frysk/hpd/TestKillCommand.java
@@ -40,10 +40,10 @@
 package frysk.hpd;
 
 import frysk.config.Config;
+import frysk.testbed.SlaveOffspring;
 
 /**
- * This class tests the "load" command basics of both loading a correct
- * executable and trying to load a non-existent executable.
+ * This class tests the "kill" command basics.
  */
 
 public class TestKillCommand extends TestLib {
@@ -151,21 +151,64 @@ public class TestKillCommand extends TestLib {
 	e.sendCommandExpectPrompt("kill", "Killing process.*");
 	/* Adding the quit/Quitting lines causes the following stack trace:
 	
-	frysk.expunit.EndOfFileException: end-of-file; expecting:  <<Quitting\.\.\..*>>; buffer <<Exception in thread "main" java.lang.RuntimeException: {frysk.proc.live.LinuxPtraceTask@2fa6f255,pid=26391,tid=26392,state=StartClonedTask.blockedOffspring} in state "StartClonedTask.blockedOffspring" did not handle handleTerminatedEvent
-	   at frysk.proc.live.State.unhandled(State.java:67)
-	   at frysk.proc.live.LinuxPtraceTaskState.handleTerminatedEvent(LinuxPtraceTaskState.java:73)
-	   at frysk.proc.live.LinuxPtraceTask.processTerminatedEvent(LinuxPtraceTask.java:233)
-	   at frysk.proc.live.LinuxWaitBuilder.terminated(LinuxWaitBuilder.java:200)
-	   at frysk.sys.Wait.wait(Wait.cxx:586)
-	   at frysk.sys.Wait.wait(Wait.java:125)
-	   at frysk.event.WaitEventLoop.block(WaitEventLoop.java:87)
-	   at frysk.event.EventLoop.runEventLoop(EventLoop.java:377)
-	   at frysk.event.EventLoop.run(EventLoop.java:487)
-	   at frysk.bindir.fhpd.main(fhpd.java:171) */
+	1) testLoadKill(frysk.hpd.TestKillCommand)frysk.expunit.EndOfFileException: end-of-file; expecting:  <<Quitting\.\.\..*>>; buffer <<quit
+java.lang.NullPointerException
+   at frysk.stepping.SteppingEngine$SteppingObserver.updateExecuted(SteppingEngine.java:1052)
+   at frysk.proc.live.LinuxPtraceProc$13.add(LinuxPtraceProc.java:690)
+   at frysk.proc.live.LinuxPtraceTaskState$StartClonedTask.handleAddObservation(LinuxPtraceTaskState.java:648)
+   at frysk.proc.live.LinuxPtraceTask.handleAddObservation(LinuxPtraceTask.java:418)
+   at frysk.proc.live.TaskObservation.handleAdd(TaskObservation.java:87)
+   at frysk.proc.live.LinuxPtraceProcState$3.handleAddObservation(LinuxPtraceProcState.java:413)
+   at frysk.proc.live.LinuxPtraceProc.handleAddObservation(LinuxPtraceProc.java:426)
+   at frysk.proc.live.LinuxPtraceProc$13.execute(LinuxPtraceProc.java:676)
+   at frysk.event.EventLoop.runEventLoop(EventLoop.java:365)
+   at frysk.event.EventLoop.run(EventLoop.java:482)
+   at frysk.bindir.fhpd.main(fhpd.java:181)
+>>
+   at frysk.expunit.Child.expectMilliseconds(Child.java:161)
+   at frysk.expunit.Expect.expect(Expect.java:158)
+   at frysk.expunit.Expect.expect(Expect.java:167)
+   at frysk.expunit.Expect.expect(Expect.java:176)
+   at frysk.hpd.TestKillCommand.testLoadKill(TestKillCommand.java:170)
+   at frysk.junit.Runner.runCases(Runner.java:197)
+   at frysk.junit.Runner.runTestCases(Runner.java:424)
+   at TestRunner.main(TestRunner.java:63) */
 
 	//e.send("quit\n");
 	//e.expect("Quitting\\.\\.\\..*");
 	e.close();
     }
     
+    /**
+     * Test killing of a single proc using the PID
+     */
+    public void testKillByPID() {
+	SlaveOffspring newProc = SlaveOffspring.createDaemon();
+	int pid = newProc.getPid().intValue();
+	e = new HpdTestbed();
+	e.sendCommandExpectPrompt("attach " + pid, "Attached to process " + pid + ".*");
+	e.sendCommandExpectPrompt("kill " + pid, "Killing process " + pid + ".*");
+	try { Thread.sleep(500); } catch (Exception e) { }
+	e.sendCommandExpectPrompt("kill " + pid, "PID " + pid + " could not be found.*");
+	e.send("quit\n");
+	e.expect("Quitting\\.\\.\\..*");
+	e.close();
+    }
+    
+    public void testKillError() {
+	SlaveOffspring newProc = SlaveOffspring.createDaemon();
+	int pid = newProc.getPid().intValue();
+	e = new HpdTestbed();
+	e.sendCommandExpectPrompt("attach " + pid, "Attached to process " + pid + ".*");
+	e.sendCommandExpectPrompt("kill abc", "Error: PID entered is not an integer.*");
+	e.send("quit\n");
+	e.expect("Quitting\\.\\.\\..*");
+	e.close();
+    }
+    
+    public void testKillErrorTwo() {
+	e = new HpdTestbed();
+	e.sendCommandExpectPrompt("kill a b c", "Too many parameters.*");
+    }
+    
 }


hooks/post-receive
--
frysk system monitor/debugger


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2008-03-13 15:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-03-13 15:53 [SCM] master: Add ability to kill a process using its PID rmoseley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).