[comp.unix.questions] Program name from PID?

bob@rscsys.UUCP (Bob Celmer) (02/12/91)

Hello Everyone:

Given a process id, how can I find out the name of the process it belongs
to?  Unfortunately, grepping ps output is not a viable option.  The specific
system is Xenix 2.3.2 running on 386 based machines.  Also, how might this
problem be solved on other Unix platforms?

Thanks.
-- 
Bob Celmer
UUCP: {fedeva,chromc}!dynasys!rscsys!bob

Disclaimer:  Al Gore and Jim Sasser seldom represent MY views...

tchrist@convex.COM (Tom Christiansen) (02/15/91)

From the keyboard of bob@rscsys.UUCP (Bob Celmer):
:Given a process id, how can I find out the name of the process it belongs
:to?  Unfortunately, grepping ps output is not a viable option.  The specific
:system is Xenix 2.3.2 running on 386 based machines.  Also, how might this
:problem be solved on other Unix platforms?

I don't know what's wrong with grepping ps output.  If for some reason, 
I just weren't allowed to do this, I would do something like this

 printf("pid %d is command %s\n", pid, getprocstruct(pid)->p_uaddr->u_comm);
		
Writing getprocstruct() is left as an excersize to the reader. Actually,
you won't be able to directdly deref the pointer in user space, but 
you get the idea.

Perhaps you should reconsider ps. :-)

--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
"With a kernel dive, all things are possible, but it sure makes it hard
 to look at yourself in the mirror the next morning."  -me

tchrist@convex.COM (Tom Christiansen) (02/16/91)

From the keyboard of longshot@en.ecn.purdue.edu (Longshot (tm)):
:	The question:  How can you look up a process name (or partial name
:  possibly wild cards, or just a short version) in kmem?  ie how do I get
:  the corresponding PID(s)? I don't have the time or patience to look through 
:  'ps' so any suggestions will be appreciated.  

Short-cuts to knowledge don't buy you as much as the longer, more
interesting route.  It's like the difference between memorizing
formulae and knowing how they were derived.  With the first method,
a memory fault will leave you up a crick without a paddle.  The second
gives you a chance to re-create the holes.

If you want a short answer and are running on either a Convex or a Sun,
there are functions in the lib(k)vm libraries to do this for you, and
they're quite quick as they map in the space.   On a Convex, use
Getuproc() from libvm.a, or simply Getproccmd() (which is what you want)
from the same library.  On a Sun, it looks like you can use kvm_getu()
from libkvm.a .

Otherwise, you're going to have to nlist the kernel to find the proc
structure, use that to find your pid's proc entry, then use the pointer
there to go find the corresponding user structure, and then there you'll
find the command name.  Of course, all this assumes a fairly standard
looking kernel -- I've not tried it on anything that's not a BSD system,
i.e. Suns, Vaxen, and Convexen.

--tom
--
Tom Christiansen		tchrist@convex.com	convex!tchrist
 "All things are possible, but not all expedient."  (in life, UNIX, and perl)

guy@auspex.auspex.com (Guy Harris) (02/18/91)

>Given a process id, how can I find out the name of the process it belongs
>to?

Others have noted various ways of fetching various information about a
process that could be considered the "name" of the process.  The two
bits of information that could be considered the process's "name" are:

	1) the "u_comm" field from the process's U area.  This is the
	   first N characters of the last component of the pathname of
	   the last program "exec"ed by the process (or the last "#!"
	   script - many systems arrange that it be the name of the
	   script, rather than the name of the interpreter on the "#!"
	   line).

	2) something extracted from the "command line" for the process. 
	   On some systems, this may appear in the U area as a character
	   string; on other systems, it may have to be extracted from
	   the top of the process's stack.

	   In the former case, the first token in that string will be
	   whatever was passed as "argv[0]" when the last "exec" was
	   done; by convention, this is usually either the full pathname
	   of the last program (or #! script) "exec"ed by the process),
	   but it need not be - see my followup to the message here with
	   the subject line "Unknown process on sparc".

	   In the latter case, the above applies; in addition, the
	   process can overwrite that string with whatever it wants to,
	   and some programs, in fact, do so.

In other words, make sure you know what you want to do with that "name",
and make sure that the "name" you're fetching provides the information
you need....

guy@auspex.auspex.com (Guy Harris) (02/18/91)

>On a Sun, it looks like you can use kvm_getu() from libkvm.a .

"kvm_getu()" gets the U area of the process, which contains "u_comm",
which is one of the possible "names" of the process.  The other possible
"name" is the command and arguments for the process, which can be
obtained with "kvm_getcmd()".

>Otherwise, you're going to have to nlist the kernel to find the proc
>structure, use that to find your pid's proc entry, then use the pointer
>there to go find the corresponding user structure, and then there you'll
>find the command name.  Of course, all this assumes a fairly standard
>looking kernel -- I've not tried it on anything that's not a BSD system,
>i.e. Suns, Vaxen, and Convexen.

Later System V systems store a character string fabricated from the
arguments passed in an "exec()" in "u_psargs".  "u_comm" is there in
AT&T S5 releases as well.  The systems I'd worry about are the ones not
derived from AT&T source, or at least the ones where the lower levels of
the system aren't derived from AT&T source.  (Enough of older BSD
systems is sufficiently derived from AT&T source; 4.3-reno's U area
isn't AT&T-derived - or, at least, "user.h" has the "AT&T-free"
copyright notice - and it does *not* have anything like "u_comm"; it
stores that information in the proc structure instead.)

I think S5R4's "/proc" file system lets you fetch that string without
having to fetch the user structure yourself.