fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / Documentation / utrace.txt
index 73858ed..0f0c80a 100644 (file)
@@ -60,19 +60,22 @@ struct pointer that is the handle used in all other utrace_* calls.
 The data argument is stored in the utrace_attached_engine structure,
 for your code to use however it wants.
 
-       void utrace_detach(struct task_struct *target,
-                          struct utrace_attached_engine *engine);
+       int utrace_detach(struct task_struct *target,
+                         struct utrace_attached_engine *engine);
 
 The utrace_detach call removes an engine from a thread.
-No more callbacks will be made after this returns.
+No more callbacks will be made after this returns success.
 
 
 An attached engine does nothing by default.
 An engine makes something happen by setting its flags.
 
-       void utrace_set_flags(struct task_struct *target,
-                             struct utrace_attached_engine *engine,
-                             unsigned long flags);
+       int utrace_set_flags(struct task_struct *target,
+                            struct utrace_attached_engine *engine,
+                            unsigned long flags);
+
+The synchronization issues related to these two calls
+are discussed further below in "Teardown Races".
 
 
        Action Flags
@@ -86,43 +89,48 @@ the thread.  The action flags available are:
 
        UTRACE_ACTION_QUIESCE
 
-               The thread will stay quiescent (see below).
-               As long as any engine asserts the QUIESCE action flag,
-               the thread will not resume running in user mode.
-               (Usually it will be in TASK_TRACED state.)
-               Nothing will wake the thread up except for SIGKILL
-               (and implicit SIGKILLs such as a core dump in
-               another thread sharing the same address space, or a
-               group exit or fatal signal in another thread in the
-               same thread group).
+               The thread will stay quiescent (see below).  As long as
+               any engine asserts the QUIESCE action flag, the thread
+               will not resume running in user mode.  (Usually it will
+               be in TASK_TRACED state.)  Nothing will wake the thread
+               up except for SIGKILL (and implicit SIGKILLs such as a
+               core dump in another thread sharing the same address
+               space, or a group exit, fatal signal, or exec in another
+               thread in the same thread group).
 
        UTRACE_ACTION_SINGLESTEP
 
-               When the thread runs, it will run one instruction
-               and then trap.  (Exiting a system call or entering a
-               signal handler is considered "an instruction" for this.)
-               This can be used only if ARCH_HAS_SINGLE_STEP #define'd
-               by <asm/tracehook.h> and evaluates to nonzero.
+               When the thread runs, it will run one instruction and
+               then trap.  (Exiting a system call or entering a signal
+               handler is considered "an instruction" for this.)  This
+               is available on most machines.  This can be used only if
+               ARCH_HAS_SINGLE_STEP is #define'd by <asm/tracehook.h>
+               and evaluates to nonzero.
 
        UTRACE_ACTION_BLOCKSTEP
 
-               When the thread runs, it will run until the next branch,
-               and then trap.  (Exiting a system call or entering a
-               signal handler is considered a branch for this.)
-               When the SINGLESTEP flag is set, BLOCKSTEP has no effect.
-               This is only available on some machines (actually none yet).
-               This can be used only if ARCH_HAS_BLOCK_STEP #define'd
-               by <asm/tracehook.h> and evaluates to nonzero.
+               When the thread runs, it will run until the next branch
+               taken, and then trap.  (Exiting a system call or
+               entering a signal handler is considered taking a branch
+               for this.)  When the SINGLESTEP flag is set, BLOCKSTEP
+               has no effect.  This is only available on some machines.
+               This can be used only if ARCH_HAS_BLOCK_STEP is
+               #define'd by <asm/tracehook.h> and evaluates to nonzero.
 
        UTRACE_ACTION_NOREAP
 
                When the thread exits or stops for job control, its
                parent process will not receive a SIGCHLD and the
-               parent's wait calls will not wake up or report the
-               child as dead.  A well-behaved tracing engine does not
-               want to interfere with the parent's normal notifications.
-               This is provided mainly for the ptrace compatibility
-               code to implement the traditional behavior.
+               parent's wait calls will not wake up or report the child
+               as dead.  Even a self-reaping thread will remain a
+               zombie.  Note that this cannot prevent the reaping done
+               when an exec is done by another thread in the same
+               thread group; in that event, a REAP event (and callback
+               if requested) will happen regardless of this flag.
+               A well-behaved tracing engine does not want to interfere
+               with the parent's normal notifications.  This is
+               provided mainly for the ptrace compatibility code to
+               implement the traditional behavior.
 
 Event flags are specified using the macro UTRACE_EVENT(TYPE).
 Each event type is associated with a report_* callback in struct
@@ -181,7 +189,7 @@ This means that it is stopped and won't start running again while we access
 it.  A quiescent thread is stopped in a place close to user mode, where the
 user state can be accessed safely; either it's about to return to user
 mode, or it's just entered the kernel from user mode, or it has already
-finished exiting (TASK_ZOMBIE).  Setting the UTRACE_ACTION_QUIESCE action
+finished exiting (EXIT_ZOMBIE).  Setting the UTRACE_ACTION_QUIESCE action
 flag will force the attached thread to become quiescent soon.  After
 setting the flag, an engine must wait for an event callback when the thread
 becomes quiescent.  The thread may be running on another CPU, or may be in
@@ -191,7 +199,7 @@ callbacks to engines that set the UTRACE_EVENT(QUIESCE) event flag.
 As long as some engine has UTRACE_ACTION_QUIESCE set, then the thread will
 remain stopped.  SIGKILL will wake it up, but it will not run user code.
 When the flag is cleared via utrace_set_flags or a callback return value,
-the thread starts running again.
+the thread starts running again.  (See also "Teardown Races", below.)
 
 During the event callbacks (report_*), the thread in question makes the
 callback from a safe place.  It is not quiescent, but it can safely access
@@ -291,7 +299,7 @@ Callback:
 This means the parent called wait, or else this was a detached thread or
 a process whose parent ignores SIGCHLD.  This cannot happen while the
 UTRACE_ACTION_NOREAP flag is set.  This is the only callback you are
-guaranteed to get (if you set the flag).
+guaranteed to get (if you set the flag; but see "Teardown Races", below).
 
 Unlike other callbacks, this can be called from the parent's context
 rather than from the traced thread itself--it must not delay the parent by
@@ -369,11 +377,12 @@ Callback:
        u32 (*report_death)(struct utrace_attached_engine *engine,
                            struct task_struct *tsk);
 
-The thread is really dead now.  If the UTRACE_ACTION_NOREAP flag is set
-after this callback, it remains an unreported zombie.  Otherwise, it might
-be reaped by its parent, or self-reap immediately.  Though the actual
-reaping may happen in parallel, a report_reap callback will always be
-ordered after a report_death callback.
+The thread is really dead now.  If the UTRACE_ACTION_NOREAP flag remains
+set after this callback, it remains an unreported zombie; If the flag was
+not set already, then it is too late to set it now--its parent has already
+been sent SIGCHLD.  Otherwise, it might be reaped by its parent, or
+self-reap immediately.  Though the actual reaping may happen in parallel, a
+report_reap callback will always be ordered after a report_death callback.
 
 UTRACE_EVENT(SYSCALL_ENTRY)    Thread has entered kernel for a system call
 Callback:
@@ -433,11 +442,11 @@ The action argument says what the signal's default disposition is:
        UTRACE_SIGNAL_TSTP      Job control stop (no stop if orphaned).
 
 This selection is made from consulting the process's sigaction and the
-default action for the signal number, but may already have been
-changed by an earlier tracing engine (in which case you see its override).
-A return value of UTRACE_ACTION_RESUME means to carry out this action.
-If instead UTRACE_SIGNAL_* bits are in the return value, that overrides
-the normal behavior of the signal.
+default action for the signal number, but may already have been changed by
+an earlier tracing engine (in which case you see its override).  A return
+value of UTRACE_ACTION_RESUME means to carry out this action.  If instead
+UTRACE_SIGNAL_* bits are in the return value, that overrides the normal
+behavior of the signal.
 
 The signal number and other details of the signal are in info, and
 this data can be changed to make the thread see a different signal.
@@ -453,3 +462,118 @@ UTRACE_SIGNAL_HOLD is a flag bit that can be OR'd into the return
 value.  It says to push the signal back on the thread's queue, with
 the signal number and details possibly changed in info.  When the
 thread is allowed to resume, it will dequeue and report it again.
+
+
+       Teardown Races
+       -------- -----
+
+Ordinarily synchronization issues for tracing engines are kept fairly
+straightforward by using quiescence (see above): you make a thread
+quiescent and then once it makes the report_quiesce callback it cannot
+do anything else that would result in another callback, until you let
+it.  This simple arrangement avoids complex and error-prone code in
+each one of a tracing engine's event callbacks to keep them serialized
+with the engine's other operations done on that thread from another
+thread of control.  However, giving tracing engines complete power to
+keep a traced thread stuck in place runs afoul of a more important
+kind of simplicity that the kernel overall guarantees: nothing can
+prevent or delay SIGKILL from making a thread die and release its
+resources.  To preserve this important property of SIGKILL, it as a
+special case can break quiescence like nothing else normally can.
+This includes both explicit SIGKILL signals and the implicit SIGKILL
+sent to each other thread in the same thread group by a thread doing
+an exec, or processing a fatal signal, or making an exit_group system
+call.  A tracing engine can prevent a thread from beginning the exit
+or exec or dying by signal (other than SIGKILL) if it is attached to
+that thread, but once the operation begins, no tracing engine can
+prevent or delay all other threads in the same thread group dying.
+
+As described above, the report_reap callback is always the final event
+in the life cycle of a traced thread.  Tracing engines can use this as
+the trigger to clean up their own data structures.  The report_death
+callback is always the penultimate event a tracing engine might see,
+except when the thread was already in the midst of dying when the
+engine attached.  Many tracing engines will have no interest in when a
+parent reaps a dead process, and nothing they want to do with a zombie
+thread once it dies; for them, the report_death callback is the
+natural place to clean up data structures and detach.  To facilitate
+writing such engines robustly, given the asynchrony of SIGKILL, and
+without error-prone manual implementation of synchronization schemes,
+the utrace infrastructure provides some special guarantees about the
+report_death and report_reap callbacks.  It still takes some care to
+be sure your tracing engine is robust to teardown races, but these
+rules make it reasonably straightforward and concise to handle a lot
+of corner cases correctly.
+
+The first sort of guarantee concerns the core data structures
+themselves.  struct utrace_attached_engine is allocated using RCU, as
+is task_struct.  If you call utrace_attach under rcu_read_lock, then
+the pointer it returns will always be valid while in the RCU critical
+section.  (Note that utrace_attach can block doing memory allocation,
+so you must consider the real critical section to start when
+utrace_attach returns.  utrace_attach can never block when not given
+the UTRACE_ATTACH_CREATE flag bit).  Conversely, you can call
+utrace_attach outside of rcu_read_lock and though the pointer can
+become stale asynchronously if the thread dies and is reaped, you can
+safely pass it to a subsequent utrace_set_flags or utrace_detach call
+and will just get an -ESRCH error return.  However, you must be sure
+the task_struct remains valid, either via get_task_struct or via RCU.
+The utrace infrastructure never holds task_struct references of its
+own.  Though neither rcu_read_lock nor any other lock is held while
+making a callback, it's always guaranteed that the task_struct and
+the struct utrace_attached_engine passed as arguments remain valid
+until the callback function returns.
+
+The second guarantee is the serialization of death and reap event
+callbacks for a given thread.  The actual reaping by the parent
+(release_task call) can occur simultaneously while the thread is
+still doing the final steps of dying, including the report_death
+callback.  If a tracing engine has requested both DEATH and REAP
+event reports, it's guaranteed that the report_reap callback will not
+be made until after the report_death callback has returned.  If the
+report_death callback itself detaches from the thread (with
+utrace_detach or with UTRACE_ACTION_DETACH in its return value), then
+the report_reap callback will never be made.  Thus it is safe for a
+report_death callback to clean up data structures and detach.
+
+The final sort of guarantee is that a tracing engine will know for
+sure whether or not the report_death and/or report_reap callbacks
+will be made for a certain thread.  These teardown races are
+disambiguated by the error return values of utrace_set_flags and
+utrace_detach.  Normally utrace_detach returns zero, and this means
+that no more callbacks will be made.  If the thread is in the midst
+of dying, utrace_detach returns -EALREADY to indicate that the
+report_death callback may already be in progress; when you get this
+error, you know that any cleanup your report_death callback does is
+about to happen or has just happened--note that if the report_death
+callback does not detach, the engine remains attached until the
+thread gets reaped.  If the thread is in the midst of being reaped,
+utrace_detach returns -ESRCH to indicate that the report_reap
+callback may already be in progress; this means the engine is
+implicitly detached when the callback completes.  This makes it
+possible for a tracing engine that has decided asynchronously to
+detach from a thread to safely clean up its data structures, knowing
+that no report_death or report_reap callback will try to do the
+same.  utrace_detach returns -ESRCH when the struct
+utrace_attached_engine has already been detached, but is still a
+valid pointer because of rcu_read_lock.  If RCU is used properly, a
+tracing engine can use this to safely synchronize its own
+independent multiple threads of control with each other and with its
+event callbacks that detach.
+
+In the same vein, utrace_set_flags normally returns zero; if the
+target thread was quiescent before the call, then after a successful
+call, no event callbacks not requested in the new flags will be made,
+and a report_quiesce callback will always be made if requested.  It
+fails with -EALREADY if you try to clear UTRACE_EVENT(DEATH) when the
+report_death callback may already have begun, if you try to clear
+UTRACE_EVENT(REAP) when the report_reap callback may already have
+begun, if you try to newly set UTRACE_ACTION_NOREAP when the target
+may already have sent its parent SIGCHLD, or if you try to newly set
+UTRACE_EVENT(DEATH), UTRACE_EVENT(QUIESCE), or UTRACE_ACTION_QUIESCE,
+when the target is already dead or dying.  Like utrace_detach, it
+returns -ESRCH when the thread has already been detached (including
+forcible detach on reaping).  This lets the tracing engine know for
+sure which event callbacks it will or won't see after utrace_set_flags
+has returned.  By checking for errors, it can know whether to clean up
+its data structures immediately or to let its callbacks do the work.