• Tejun Heo's avatar
    signal: Use GROUP_STOP_PENDING to stop once for a single group stop · 39efa3ef
    Tejun Heo authored
    Currently task->signal->group_stop_count is used to decide whether to
    stop for group stop.  However, if there is a task in the group which
    is taking a long time to stop, other tasks which are continued by
    ptrace would repeatedly stop for the same group stop until the group
    stop is complete.
    
    Conversely, if a ptraced task is in TASK_TRACED state, the debugger
    won't get notified of group stops which is inconsistent compared to
    the ptraced task in any other state.
    
    This patch introduces GROUP_STOP_PENDING which tracks whether a task
    is yet to stop for the group stop in progress.  The flag is set when a
    group stop starts and cleared when the task stops the first time for
    the group stop, and consulted whenever whether the task should
    participate in a group stop needs to be determined.  Note that now
    tasks in TASK_TRACED also participate in group stop.
    
    This results in the following behavior changes.
    
    * For a single group stop, a ptracer would see at most one stop
      reported.
    
    * A ptracee in TASK_TRACED now also participates in group stop and the
      tracer would get the notification.  However, as a ptraced task could
      be in TASK_STOPPED state or any ptrace trap could consume group
      stop, the notification may still be missing.  These will be
      addressed with further patches.
    
    * A ptracee may start a group stop while one is still in progress if
      the tracer let it continue with stop signal delivery.  Group stop
      code handles this correctly.
    
    Oleg:
    
    * Spotted that a task might skip signal check even when its
      GROUP_STOP_PENDING is set.  Fixed by updating
      recalc_sigpending_tsk() to check GROUP_STOP_PENDING instead of
      group_stop_count.
    
    * Pointed out that task->group_stop should be cleared whenever
      task->signal->group_stop_count is cleared.  Fixed accordingly.
    
    * Pointed out the behavior inconsistency between TASK_TRACED and
      RUNNING and the last behavior change.
    Signed-off-by: default avatarTejun Heo <tj@kernel.org>
    Acked-by: default avatarOleg Nesterov <oleg@redhat.com>
    Cc: Roland McGrath <roland@redhat.com>
    39efa3ef
signal.c 70.9 KB