Bug 201441 - Perhaps the proc(5) man page should mention LWPIDs?
Summary: Perhaps the proc(5) man page should mention LWPIDs?
Status: RESOLVED CODE_FIX
Alias: None
Product: Documentation
Classification: Unclassified
Component: man-pages (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: documentation_man-pages@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-10-16 14:50 UTC by Philip Dumont
Modified: 2018-11-05 14:52 UTC (History)
1 user (show)

See Also:
Kernel Version:
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Philip Dumont 2018-10-16 14:50:01 UTC
The proc(5) man page says that every PID has a corresponding /proc/[pid] directory.

It sure would be nice if the page made mention of the fact that there are also some /proc/[lwpid] directories where, for multi-threaded processed, the LWP's lwpid is not a pid.

Now, the page never does (as far as I've read) assert that all /proc/[NNNN] directories are named for PIDs.  So it is not, strictly speaking, incorrect.  But an argument could be made that it is incomplete.

At least one reader (me) could have been saved a bit of grief if the page mentioned LWPs.

Any chance it could be added?

I'm looking at RH6.10, kernel 2.6.32-754.3.5.el6.x86_64, and the man page appears to be installed by an RPM named man-pages-overrides-6.10.0-1.el6.noarch.
Comment 1 Michael Kerrisk 2018-11-04 23:03:41 UTC
Hello Philip,

Just by the way, how did you discover /proc/TID? I ask, because I discovered it myself only relatively recently and somewhat by accident.

I've applied the patch below to proc(5).

Thanks,

Michael

diff --git a/man5/proc.5 b/man5/proc.5
index 69f7f7783..aa8171ecd 100644
--- a/man5/proc.5
+++ b/man5/proc.5
@@ -173,6 +173,34 @@ which contain corresponding information about each of the threads
 in the process, where
 .I tid
 is the kernel thread ID of the thread.
+.IP
+The
+.I /proc/[pid]
+subdirectories are visible when iterating through
+.I /proc
+with
+.BR getdents (2)
+(and thus are visible when one uses
+.BR ls (1)
+to view the contents of
+.IR /proc ).
+.TP
+.IR /proc/[tid] " subdirectories"
+Each one of these subdirectories contains files and subdirectories
+exposing information about the thread with the corresponding thread ID.
+.IP
+The
+.I /proc/[tid]
+subdirectories are
+.I not
+visible when iterating through
+.I /proc
+with
+.BR getdents (2)
+(and thus are
+.I not
+visible when one uses
+.BR ls (1)
 to view the contents of
 .IR /proc ).
 .TP
@@ -196,8 +224,7 @@ expose system-wide information.
 All of the above are described in more detail below.
 .\"
 .SS Files and directories
-The following list provides details of many of
-the files and directories under the
+The following list provides details of many of the files and directories under the
 .I /proc
 hierarchy.
 .TP
@@ -2869,6 +2896,33 @@ Permission to access this file is governed by a ptrace access mode
 check; see
 .BR ptrace (2).
 .TP
+.IR /proc/[tid]
+There  is a numerical subdirectory for each running thread
+that is not a thread group leader
+(i.e., a thread whose thread ID is not the same as its process ID);
+the subdirectory is named by the thread ID.
+Each one of these subdirectories contains files and subdirectories
+exposing information about the thread with the thread ID
+.IR tid .
+The contents of these directories are the same as the corresponding
+.IR /proc/self/task/[tid]
+directories.
+.IP
+The
+.I /proc/[tid]
+subdirectories are
+.I not
+visible when iterating through
+.I /proc
+with
+.BR getdents (2)
+(and thus are
+.I not
+visible when one uses
+.BR ls (1)
+to view the contents of
+.IR /proc ).
+.TP
 .I /proc/apm
 Advanced power management version and battery information when
 .B CONFIG_APM
Comment 2 Philip Dumont 2018-11-05 14:52:49 UTC
(In reply to Michael Kerrisk from comment #1)
> Hello Philip,
> 
> Just by the way, how did you discover /proc/TID? I ask, because I discovered
> it myself only relatively recently and somewhat by accident.
> 
> I've applied the patch below to proc(5).
> 
> Thanks,
> 
> Michael
> 
> diff --git a/man5/proc.5 b/man5/proc.5
> index 69f7f7783..aa8171ecd 100644
> --- a/man5/proc.5
> +++ b/man5/proc.5
> @@ -173,6 +173,34 @@ which contain corresponding information about each of
> the threads
>  in the process, where
>  .I tid
>  is the kernel thread ID of the thread.
> +.IP
> +The
> +.I /proc/[pid]
> +subdirectories are visible when iterating through
> +.I /proc
> +with
> +.BR getdents (2)
> +(and thus are visible when one uses
> +.BR ls (1)
> +to view the contents of
> +.IR /proc ).
> +.TP
> +.IR /proc/[tid] " subdirectories"
> +Each one of these subdirectories contains files and subdirectories
> +exposing information about the thread with the corresponding thread ID.
> +.IP
> +The
> +.I /proc/[tid]
> +subdirectories are
> +.I not
> +visible when iterating through
> +.I /proc
> +with
> +.BR getdents (2)
> +(and thus are
> +.I not
> +visible when one uses
> +.BR ls (1)
>  to view the contents of
>  .IR /proc ).
>  .TP
> @@ -196,8 +224,7 @@ expose system-wide information.
>  All of the above are described in more detail below.
>  .\"
>  .SS Files and directories
> -The following list provides details of many of
> -the files and directories under the
> +The following list provides details of many of the files and directories
> under the
>  .I /proc
>  hierarchy.
>  .TP
> @@ -2869,6 +2896,33 @@ Permission to access this file is governed by a
> ptrace access mode
>  check; see
>  .BR ptrace (2).
>  .TP
> +.IR /proc/[tid]
> +There  is a numerical subdirectory for each running thread
> +that is not a thread group leader
> +(i.e., a thread whose thread ID is not the same as its process ID);
> +the subdirectory is named by the thread ID.
> +Each one of these subdirectories contains files and subdirectories
> +exposing information about the thread with the thread ID
> +.IR tid .
> +The contents of these directories are the same as the corresponding
> +.IR /proc/self/task/[tid]
> +directories.
> +.IP
> +The
> +.I /proc/[tid]
> +subdirectories are
> +.I not
> +visible when iterating through
> +.I /proc
> +with
> +.BR getdents (2)
> +(and thus are
> +.I not
> +visible when one uses
> +.BR ls (1)
> +to view the contents of
> +.IR /proc ).
> +.TP
>  .I /proc/apm
>  Advanced power management version and battery information when
>  .B CONFIG_APM

Yes, it wasn't until after I filed the bug that I found out that if you get a listing of the /proc directory, the LWPIDs don't show up.  It's only if you attempt to reference /proc/LWPID that it's existence becomes known.  Neat trick, except for when it trips you up.  I get not wanting to clutter /proc with a lot of extra stuff that only marginally belongs there, but I wonder if a better solution to that might have been to tuck all the LWPIDs in a subdirectory -- maybe /proc/lpws -- rather than make them existent but invisible.  Oh well.

I found out about it because I tried to write some init scripts for a group of related programs, all multithreaded, all java.  For reasons I can't remember, I copied some stuff out of /etc/init.d/functions, rather than used the functions themselves.  One of the things I copied was a test for whether or not a PID was alive that went like this:

  [ -d "/proc/$pid" ]

Well, if $pid is an LWPid, that test will pass incorrectly.  And because my init scripts were starting up several multithreaded programs, it would occasionally happen that one of the earlier-started multithreaded programs would get a non-main-thread LWPid that just happened to be the PID of one of the later-started programs last time the system was booted.  And so the later-started program, when the function checked if the PID existed, would be fooled by the LWPID, and wouldn't start, because it thought it was already started.

Now, at the time I filed the doc bug, I had completely forgotten that I had copied that '[ -d "/proc/$pid" ]' idea from /etc/init.d/functions, and thought I had come up with it myself.  Now that I remember, I supposed I should file a bug against /etc/init.d/functions.  For what it's worth, I fixed it locally by adding to the test:

  [ -d "/proc/$pid" ] && /bin/egrep -q "Tgid:[[:space:]]*$pid[[:space:]]*$" /proc/$pid/status

Also note...  It would appear that functions like killproc() and status() have a "-b binary" option added to help with disambiguation in cases of pid collision (regardless of whether or not the collision involves an LWPID).  In my case, though, that didn't help much, since all of my init scripts started java programs.  They all had the same binary -- java.  So, to get around that problem, I added to my own hacked-up copy of the functions another option where you could specify command-line options to disambiguate.

Note You need to log in before you can comment on or make changes to this bug.