From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1655 invoked by alias); 18 Jan 2008 07:33:01 -0000 Received: (qmail 1614 invoked by uid 367); 18 Jan 2008 07:32:59 -0000 Date: Fri, 18 Jan 2008 07:33:00 -0000 Message-ID: <20080118073259.1598.qmail@sourceware.org> From: cagney@sourceware.org To: frysk-cvs@sourceware.org Subject: [SCM] master: frysk-core/frysk/proc/live/ChangeLog X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: c032a5bd0673fe5cd9b0c172354f0928efdfa915 X-Git-Newrev: e463ac8102efbc44d7f39c190085ff0522819fd9 Mailing-List: contact frysk-cvs-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: frysk-cvs-owner@sourceware.org Reply-To: frysk@sourceware.org X-SW-Source: 2008-q1/txt/msg00091.txt.bz2 The branch, master has been updated via e463ac8102efbc44d7f39c190085ff0522819fd9 (commit) from c032a5bd0673fe5cd9b0c172354f0928efdfa915 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit e463ac8102efbc44d7f39c190085ff0522819fd9 Author: Andrew Cagney Date: Fri Jan 18 02:30:13 2008 -0500 frysk-core/frysk/proc/live/ChangeLog 2008-01-18 Andrew Cagney * LinuxPtraceProcState.java: Move attach SIGCONT from here ... * LinuxPtraceTaskState.java: ... to here; wait for SIGCONT. ----------------------------------------------------------------------- Summary of changes: frysk-core/frysk/proc/live/ChangeLog | 3 + .../frysk/proc/live/LinuxPtraceProcState.java | 11 - .../frysk/proc/live/LinuxPtraceTaskState.java | 217 +++++++++++--------- 3 files changed, 121 insertions(+), 110 deletions(-) First 500 lines of diff: diff --git a/frysk-core/frysk/proc/live/ChangeLog b/frysk-core/frysk/proc/live/ChangeLog index 4c3f582..eeaf05f 100644 --- a/frysk-core/frysk/proc/live/ChangeLog +++ b/frysk-core/frysk/proc/live/ChangeLog @@ -1,5 +1,8 @@ 2008-01-18 Andrew Cagney + * LinuxPtraceProcState.java: Move attach SIGCONT from here ... + * LinuxPtraceTaskState.java: ... to here; wait for SIGCONT. + * LinuxPtraceTaskState.java: Convert a SIGCONT during the main task's attach back into a SIGSTOP; pass pending signals back when detaching. diff --git a/frysk-core/frysk/proc/live/LinuxPtraceProcState.java b/frysk-core/frysk/proc/live/LinuxPtraceProcState.java index 841e914..ce77c57 100644 --- a/frysk-core/frysk/proc/live/LinuxPtraceProcState.java +++ b/frysk-core/frysk/proc/live/LinuxPtraceProcState.java @@ -39,8 +39,6 @@ package frysk.proc.live; -import frysk.sys.Signal; -import frysk.sys.proc.Status; import java.util.Iterator; import java.util.Collection; import java.util.HashSet; @@ -167,15 +165,6 @@ abstract class LinuxPtraceProcState extends State { } // Tell the main task to get things started. mainTask.performAttach (); - // The attach has been initiated and the process state - // should transition to (T) TRACED. If it is instead in - // (T) STOPPED then the process is stuck (suspended), send - // it a SIGSTOP to unwedge it. /proc/status is used as - // that differentiates between STOPPED an TRACED. - if (Status.isStopped(proc.getPid())) { - // wake the suspended process - Signal.CONT.tkill(proc.getPid()); - } return new Attaching.ToMainTask (mainTask); } /** diff --git a/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java b/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java index 184c68c..09985ac 100644 --- a/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java +++ b/frysk-core/frysk/proc/live/LinuxPtraceTaskState.java @@ -39,6 +39,7 @@ package frysk.proc.live; +import frysk.sys.proc.Status; import frysk.proc.TaskObserver; import frysk.proc.Observer; import frysk.proc.Observable; @@ -181,116 +182,134 @@ class LinuxPtraceTaskState extends State { logger.log (Level.FINE, "{0} handleRemoval\n", task); return destroyed; } - LinuxPtraceTaskState handleAttach (LinuxPtraceTask task) - { + LinuxPtraceTaskState handleAttach(LinuxPtraceTask task) { logger.log (Level.FINE, "{0} handleAttach\n", task); task.sendAttach (); - return attaching; + if (task.getProc().getMainTask() == task + && Status.isStopped(task.getTid())) { + // The attach has been initiated on the main task + // of the process; the process state should + // transition to (T) TRACED. If it is instead (T) + // STOPPED then the process is stuck (suspended), + // send it a SIGSTOP to unwedge it. /proc/status + // is used as that differentiates between STOPPED + // an TRACED. + logger.log(Level.FINE, + "{0} wake the suspended process", task); + Signal.CONT.tkill(task.getTid()); + return new Attaching(true); + } else { + return new Attaching(false); + } } }; /** * The task is in the process of being attached. */ - private static final LinuxPtraceTaskState attaching = new LinuxPtraceTaskState("attaching") - { - private LinuxPtraceTaskState transitionToAttached (LinuxPtraceTask task, int signal) - { - ((LinuxPtraceProc)task.getProc()).performTaskAttachCompleted (task); - return new Attached.WaitForContinueOrUnblock (signal); - } - LinuxPtraceTaskState handleStoppedEvent (LinuxPtraceTask task) - { - logger.log (Level.FINE, "{0} handleStoppedEvent\n", task); - return transitionToAttached (task, 0); - } - LinuxPtraceTaskState handleSignaledEvent (LinuxPtraceTask task, int signal) - { - logger.log (Level.FINE, "{0} handleSignaledEvent, signal: {1}\n ", new Object[] {task,new Integer(signal)}); - if (task.getProc().getMainTask() == task - && Signal.CONT.equals(signal)) - // Its the cont signal sent to this task to wake - // it up from it's slumber; turn it back into a - // SIGSTOP. - return transitionToAttached (task, Signal.STOP.intValue()); - else - return transitionToAttached (task, signal); - } - LinuxPtraceTaskState handleTrappedEvent (LinuxPtraceTask task) - { - logger.log (Level.FINE, "{0} handleTrappedEvent\n", task); - return transitionToAttached (task, 0); - } - LinuxPtraceTaskState handleDisappearedEvent (LinuxPtraceTask task, Throwable w) - { - logger.log (Level.FINE, "{0} handleDisappearedEvent\n", task); - // Ouch, the task disappeared before the attach - // reached it, just abandon this one (but ack the - // operation regardless). - ((LinuxPtraceProc)task.getProc()).performTaskAttachCompleted (task); - ((LinuxPtraceProc)task.getProc()).remove (task); - return destroyed; - } - LinuxPtraceTaskState handleTerminatedEvent (LinuxPtraceTask task, boolean signal, - int value) - { - logger.log (Level.FINE, "{0} processTerminatedEvent\n", task); - // Ouch, the task terminated before the attach - // reached it, just abandon this one (but ack the - // operation regardless). - ((LinuxPtraceProc)task.getProc()).performTaskAttachCompleted (task); - ((LinuxPtraceProc)task.getProc()).remove (task); - return destroyed; - } - LinuxPtraceTaskState handleDetach (LinuxPtraceTask task, boolean shouldRemoveObservers) - { - logger.log (Level.FINE, "{0} handleDetach\n", task); - return detaching; - } - - /** - * Unblocking in attaching state is really a noop since - * no observer should have been triggered yet, so no - * observer should be blocking yet (but we allow a stray - * unblock). - */ - LinuxPtraceTaskState handleUnblock (LinuxPtraceTask task, - TaskObserver observer) - { - logger.log (Level.FINE, "{0} handleUnblock\n", task); - // Sanity check - if (task.blockers.remove(observer)) - { - throw new RuntimeException - ("blocked observer in attaching state unblock? " - + observer); - } + static private class Attaching extends LinuxPtraceTaskState { + private final boolean waitForSIGCONT; + Attaching(boolean waitForSIGCONT) { + super("attaching"); + this.waitForSIGCONT = waitForSIGCONT; + } + private LinuxPtraceTaskState transitionToAttached(LinuxPtraceTask task, + int signal) { + ((LinuxPtraceProc)task.getProc()).performTaskAttachCompleted (task); + return new Attached.WaitForContinueOrUnblock (signal); + } + LinuxPtraceTaskState handleStoppedEvent(LinuxPtraceTask task) { + logger.log (Level.FINE, "{0} handleStoppedEvent\n", task); + if (waitForSIGCONT) { + logger.log(Level.FINE, "{0} wait for CONT behind STOP\n", + task); + // There's a SIGCONT behind this SIGSTOP; wait for + // that too. return this; + } else { + return transitionToAttached(task, 0); } - - /** - * All observer can be added (but won't trigger yet) in - * attaching state. - */ - LinuxPtraceTaskState handleAddObservation(LinuxPtraceTask task, - TaskObservation observation) - { - logger.log (Level.FINE, "{0} handleAddObservation\n", task); - observation.add(); - return this; + } + LinuxPtraceTaskState handleSignaledEvent(LinuxPtraceTask task, + int signal) { + logger.log (Level.FINE, "{0} handleSignaledEvent, signal: {1}\n ", new Object[] {task,new Integer(signal)}); + if (waitForSIGCONT && Signal.CONT.equals(signal)) { + logger.log(Level.FINE, "{0} woken from slumber\n", task); + // Its the cont signal sent to this task to wake it up + // from it's slumber; turn it back into a SIGSTOP and + // continue. + return transitionToAttached (task, Signal.STOP.intValue()); + } else { + return transitionToAttached (task, signal); } - - /** - * Deleting an observer is always allowd in attaching state. - */ - LinuxPtraceTaskState handleDeleteObservation(LinuxPtraceTask task, - TaskObservation observation) - { - logger.log (Level.FINE, "{0} handleDeleteObservation\n", task); - observation.delete(); - return handleUnblock(task, observation.getTaskObserver()); + } + LinuxPtraceTaskState handleTrappedEvent(LinuxPtraceTask task) { + logger.log (Level.FINE, "{0} handleTrappedEvent\n", task); + return transitionToAttached (task, 0); + } + LinuxPtraceTaskState handleDisappearedEvent(LinuxPtraceTask task, + Throwable w) { + logger.log (Level.FINE, "{0} handleDisappearedEvent\n", task); + // Ouch, the task disappeared before the attach reached + // it, just abandon this one (but ack the operation + // regardless). + ((LinuxPtraceProc)task.getProc()).performTaskAttachCompleted (task); + ((LinuxPtraceProc)task.getProc()).remove (task); + return destroyed; + } + LinuxPtraceTaskState handleTerminatedEvent(LinuxPtraceTask task, + boolean signal, int value) { + logger.log (Level.FINE, "{0} processTerminatedEvent\n", task); + // Ouch, the task terminated before the attach reached it, + // just abandon this one (but ack the operation + // regardless). + ((LinuxPtraceProc)task.getProc()).performTaskAttachCompleted (task); + ((LinuxPtraceProc)task.getProc()).remove (task); + return destroyed; + } + LinuxPtraceTaskState handleDetach(LinuxPtraceTask task, + boolean shouldRemoveObservers) { + logger.log (Level.FINE, "{0} handleDetach\n", task); + return detaching; + } + /** + * Unblocking in attaching state is really a noop since + * no observer should have been triggered yet, so no + * observer should be blocking yet (but we allow a stray + * unblock). + */ + LinuxPtraceTaskState handleUnblock(LinuxPtraceTask task, + TaskObserver observer) { + logger.log (Level.FINE, "{0} handleUnblock\n", task); + // Sanity check + if (task.blockers.remove(observer)) { + throw new RuntimeException + ("blocked observer in attaching state unblock? " + + observer); } - }; + return this; + } + /** + * All observer can be added (but won't trigger yet) in + * attaching state. + */ + LinuxPtraceTaskState handleAddObservation(LinuxPtraceTask task, + TaskObservation observation) { + logger.log (Level.FINE, "{0} handleAddObservation\n", task); + observation.add(); + return this; + } + /** + * Deleting an observer is always allowd in attaching state. + */ + LinuxPtraceTaskState handleDeleteObservation(LinuxPtraceTask task, + TaskObservation observation) + { + logger.log (Level.FINE, "{0} handleDeleteObservation\n", task); + observation.delete(); + return handleUnblock(task, observation.getTaskObserver()); + } + } /** * The task is attached, and waiting to be either continued, or @@ -1264,7 +1283,7 @@ class LinuxPtraceTaskState extends State { LinuxPtraceTaskState handleAttach (LinuxPtraceTask task) { logger.log (Level.FINE, "{0} handleAttach\n", task); - return attaching; + return new Attaching(false); } LinuxPtraceTaskState handleStoppedEvent (LinuxPtraceTask task) { hooks/post-receive -- frysk system monitor/debugger