At SingleStore, we are out to build awesome software and we’re always trying to solve hard problems. A few days ago, I uncovered a cool Linux mystery with some colleagues and fixed it. We thought sharing that experience might benefit others.
The scene of the crimeWhile developing an internal tool to get stack traces, we decided to use the `SYS_tgkill`t
tgkill
ttgid
ttid
tt
tgid
t/proc/self/status
tcat /proc/self/status
Name: cat
State: R (running)
Tgid: 26473
Ngid: 0
Pid: 26473
PPid: 26378
... <snip> ...
The first prototype of this internal tool used the `SYS_getpid`t
tgid
tThis worked for most developers at SingleStore, but some developers were running environments with newer Linux distributions and it didn’t seem to work in those instances.
t
/proc/self/status
tbeforetTgid
tcommit 3e42979e65dace1f9268dd5440e5ab096b8dee59
Author: Richard W.M. Jones <rjones@redhat.com>
Date: Fri May 20 17:00:05 2016 -0700
procfs: expose umask in /proc/<PID>/status
... <snip> ...
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -162,6 +176,10 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
ngid = task_numa_group_id(p);
cred = get_task_cred(p);
+ umask = get_task_umask(p);
+ if (umask >= 0)
+ seq_printf(m, "Umask:\t%#04o\n", umask);
+
task_lock(p);
if (p->files)
max_fds = files_fdtable(p->files)->max_fds;
task_unlock(p);
rcu_read_unlock();
seq_printf(m,
"State:\t%s\n"
"Tgid:\t%d\n"
"Ngid:\t%d\n"
The motive
t
tgid
tpid
tLinux reference on thread groups states:Thread groups were a feature added in Linux 2.4 to support the POSIX threads notion of a set of threads that share a single PID. Internally, this shared PID is the so-called thread group identifier (TGID) for the thread group. Since Linux 2.4, calls to getpid(2) return the TGID of the caller.
t
/proc/self/status
tTgid
tPid
tThe culprit
t
/proc/self/status
tfs/proc/array.c
tTgid
tPid
ttgid = task_tgid_nr_ns(p, ns);
... <snip> ...
seq_put_decimal_ull(m, "\nTgid:\t", tgid);
seq_put_decimal_ull(m, "\nNgid:\t", ngid);
seq_put_decimal_ull(m, "\nPid:\t", pid_nr_ns(pid, ns));
t
task_tgid_nr_ns
tkernel/pid.c
tPid
tTgid
tpid_t task_tgid_nr_ns(struct task_struct *tsk, struct pid_namespace *ns){return pid_nr_ns(task_tgid(tsk), ns);} EXPORT_SYMBOL(task_tgid_nr_ns);
t
task_tgid
tinclude/linux/sched.h
tpid
tstatic inline struct pid *task_tgid(struct task_struct *task){return task->group_leader->pids[PIDTYPE_PID].pid;}
Elementary, my dear Watsont
status
tgetpid
t