We don't allow SIGSTOP and ptrace attach to these threads, and that confuses applications like gdb that assume they can attach to any thread listed in /proc/<pid>/task/. gdb then enters an infinite loop of retrying attach, even though it fails with the same error (-EPERM) every time. Skip over PF_IO_WORKER threads in the proc task setup. We can't just terminate the when we find a PF_IO_WORKER thread, as there's no real ordering here. It's perfectly feasible to have the first thread be an IO worker, and then a real thread after that. Hence just implement the skip. Reported-by: Stefan Metzmacher <metze@xxxxxxxxx> Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> --- fs/proc/base.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/fs/proc/base.c b/fs/proc/base.c index 3851bfcdba56..abff2fe10bfa 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -3723,7 +3723,7 @@ static struct task_struct *first_tid(struct pid *pid, int tid, loff_t f_pos, */ pos = task = task->group_leader; do { - if (!nr--) + if (same_thread_group(task, pos) && !nr--) goto found; } while_each_thread(task, pos); fail: @@ -3744,16 +3744,22 @@ static struct task_struct *first_tid(struct pid *pid, int tid, loff_t f_pos, */ static struct task_struct *next_tid(struct task_struct *start) { - struct task_struct *pos = NULL; + struct task_struct *tmp, *pos = NULL; + rcu_read_lock(); - if (pid_alive(start)) { - pos = next_thread(start); - if (thread_group_leader(pos)) - pos = NULL; - else - get_task_struct(pos); + if (!pid_alive(start)) + goto no_thread; + list_for_each_entry_rcu(tmp, &start->thread_group, thread_group) { + if (!thread_group_leader(tmp) && same_thread_group(start, tmp)) { + get_task_struct(tmp); + pos = tmp; + break; + } } +no_thread: rcu_read_unlock(); + if (!pos) + return NULL; put_task_struct(start); return pos; } -- 2.31.0