[comp.unix.wizards] finding the u structure in /dev/mem on SYSV

fsg@holos0.UUCP (Frank Glass) (08/05/88)

I am writing a routine to list UNIX processes and their respective ages.
I need for the source to be reasonably portable across System V (or at
least USG) breeds of machines.  Getting to the proc table seems simple
and consistent:  use nl() to get proc address from /unix, seek to that address
in /dev/kmem and read the first element in.  Any macros I need seem to be in
sys/sysmacros.h.  The next problem is getting to the u structure in /dev/mem.
(I have no problem finding u structures of swapped processes in /dev/swap).
I can't seem to find a _consistent_ macro to relate the pointer or click
number in the proc structure to the offset into /dev/mem.  I am using
AT&T 3b2, NCR Tower 32 and a Xenix 286 machine.  I have solved the problem
on two of the three, but there seems not to be a common solution and I have
many machines to go.

Any email help here will be much appreciated.  
My CORRECT uucp routing: ...!gatech!holos0!fsg
-- 
Frank Glass
Holos Software, Inc.
Voice: (404) 496-1358
UUCP: ...!gatech!holos0!fsg

brianb@marque.mu.edu (Brian Bebeau) (08/09/88)

In article <1240@holos0.UUCP> fsg@holos0.UUCP (Frank Glass) writes:
>I am writing a routine to list UNIX processes and their respective ages.
>I need for the source to be reasonably portable across System V (or at
>least USG) breeds of machines.  
>The next problem is getting to the u structure in /dev/mem.
>I can't seem to find a _consistent_ macro to relate the pointer or click
>number in the proc structure to the offset into /dev/mem.  I am using
>AT&T 3b2, NCR Tower 32 and a Xenix 286 machine.  I have solved the problem
>on two of the three, but there seems not to be a common solution and I have
>many machines to go.
>
>Frank Glass
and fox@marlow.uucp (Paul Fox) writes...
>I am trying to write/port the BSD 'top' utility
>posted to usenet sometime ago, to Unix V.3. 
>
>I've successfully managed to port it to SunOS 4 after a lot of changes,
>but am having problems with the u-area.
>
>Given that we start from the struct proc of a process, how
>do we get to the u-area, if (a) the process/u-area is in memory,
>and (b) the process/u-area is swapped out.

I've written a program that reads the process struct and u area to get
other useful info that ps doesn't tell you, and I've run into this so
I thought I'd post my experiences. Following are some code fragments
that show just how un-portable any scheme can be. These are from a 
3b15, a 3b5, and a 3b2. Each requires something different, yet they're
all the same processor! I'd hate to change processors much less vendors.
In fact, I've been working on the 6386 version, and that's much worse,
involving reading the U area page table, then reading in pages of the 
U area, or something like that. It's been a pain so far. Note the 
BSHIFT variable. Brandon Allberry's utree program notes he had to 
hard-code an 11 instead to get it to work on his Pyramid.

======================================================================
/* read user area on 3b15 */
	if (mproc.p_flag & SLOAD) {
		lseek(mem, (long)(ctob(mproc.p_addr)) & ~MAINSTORE, 0)
	}
	else {
		lseek(swap, (long)(swplo + mproc.p_region->p_regva), 0)
	}
======================================================================
/* read user area on 3b2 */
	if (mproc.p_flag & SLOAD) {
		lseek(mem, (long)(ctob(mproc.p_addr)) & ~MAINSTORE, 0)
	}
	else {
		lseek(swap, (swplo + mproc.p_swaddr + ctod(mproc.p_swsize -
				USIZE - mproc.p_ssize)) << BSHIFT, 0) 
	}
======================================================================
/* read user area on 3b5 */
	if (mproc.p_flag & SLOAD) {
		lseek(mem, (long)(ctob(mproc.p_addr)) & ~VUSER, 0)
	}
	else {
		lseek(swap, (swplo + mproc.p_swaddr + ctod(mproc.p_swsize -
				USIZE)) << BSHIFT, 0) == -1L)
	}
======================================================================
---------------------------------------------------------------------------
Brian Bebeau				 Marquette University		

DOMAIN:  brianb@marque.mu.edu 
  UUCP:  {uwvax,rutgers,uunet}!marque!brianb
  ARPA:  brianb%marque.uucp@csd1.milw.wisc.edu     BITNET:  6877BEBE@MUCSD
---------------------------------------------------------------------------

allbery@ncoast.UUCP (Brandon S. Allbery) (08/10/88)

As quoted from <244@marque.mu.edu> by brianb@marque.mu.edu (Brian Bebeau):
+---------------
| U area, or something like that. It's been a pain so far. Note the 
| BSHIFT variable. Brandon Allberry's utree program notes he had to 
| hard-code an 11 instead to get it to work on his Pyramid.
+---------------

Don't insult the Pyramid; it doesn't deserve it.  ;-) It was a Plexus P/60,
not a Pyramid.

++Brandon
-- 
Brandon S. Allbery, uunet!marque!ncoast!allbery			DELPHI: ALLBERY
	    For comp.sources.misc send mail to ncoast!sources-misc

rbj@nav.icst.nbs.gov (Root Boy Jim) (08/17/88)

? From: fsg@holos0.UUCP (Frank Glass)

? I am writing a routine to list UNIX processes and their respective ages.
? I need for the source to be reasonably portable across System V (or at
? least USG) breeds of machines.  Getting to the proc table seems simple
? and consistent:  use nl() to get proc address from /unix, seek to that address
? in /dev/kmem and read the first element in.  Any macros I need seem to be in
? sys/sysmacros.h.  The next problem is getting to the u structure in /dev/mem.

Just a side issue, but what if things change during your poking around in
/dev/{kmem,swap}? How do ps-like programs deal with such things? 

? Frank Glass
? Holos Software, Inc.
? Voice: (404) 496-1358
? UUCP: ...!gatech!holos0!fsg

	(Root Boy) Jim Cottrell	<rbj@icst-cmr.arpa>
	National Bureau of Standards
	Flamer's Hotline: (301) 975-5688
	The opinions expressed are solely my own
	and do not reflect NBS policy or agreement
	Careful with that VAX Eugene!

lvc@cbnews.ATT.COM (Lawrence V. Cipriani) (08/18/88)

In article <16837@adm.ARPA> rbj@nav.icst.nbs.gov (Root Boy Jim) writes:
>Just a side issue, but what if things change during your poking around in
>/dev/{kmem,swap}? How do ps-like programs deal with such things? 
>	(Root Boy) Jim Cottrell	<rbj@icst-cmr.arpa>
	(and his 6 line .signature :-)

Some programs, set their nice value very high (or is that very low?)
to help ensure that things don't change, ie get swapped out or whatever.
Still no guarantee, but it seems to work usually.

-- 
Larry Cipriani, AT&T Network Systems, Columbus OH, (614) 860-4999

ag@elgar.UUCP (Keith Gabryelski) (08/18/88)

In article <16837@adm.ARPA> rbj@nav.icst.nbs.gov (Root Boy Jim) writes:
>? From: fsg@holos0.UUCP (Frank Glass)
>
>? I am writing a routine to list UNIX processes and their respective ages.
>? I need for the source to be reasonably portable across System V (or at
>? least USG) breeds of machines.  Getting to the proc table seems simple
>? and consistent:  use nl() to get proc address from /unix, seek to that
>? address

Kay...  You could also save the proc address in a file so you won't
have to do the nlist every time.  Check the access time of your
proc-address-file against the kernel file and if the kernel has been
modified recently, re-nlist the kernel.

>? in /dev/kmem and read the first element in.  Any macros I need seem to
>? be in
>? sys/sysmacros.h.  The next problem is getting to the u structure in
>? /dev/mem.

What you want to do is read in the entire proc array so you don't have
to deal with proccess-exiting contigencies.  Then for each idividual
proc entry check to see if the process is swapped out.  If it is, look
at the p_swaddr and compute the u struct location in /dev/swap.  If
the process is not swapped then p_addr is used to compute the address
of the u struct in /dev/mem.  Depending on the port and whether your
system uses pages or whatnot then p_*addr's may point to block numbers
or page table entries or whatever.  Usually there is enough
information in the header files to go from here.

I have a finger program written for SCO Xenix 386.  It has been ported
ot the 3b1 and I started porting to the 3b5 and the 286 Xenix machine.
I will send it to you if you would like.  Send me mail.

>Just a side issue, but what if things change during your poking around in
>/dev/{kmem,swap}? How do ps-like programs deal with such things? 

Usually, you want to read in the entire proc array then read in each
individual u structs.  Hopefully most of the process will stay put
during these reads.

If the u struct does not look valid then I think the most reasonable
thing to do is discard the current process.  It probably exited during
your reads or did something nasty.

Pax, Keith



-- 
  "If green is all there is to be, then green is good enough for me" - ktf
[  Keith   ]  UUCP: {ucsd, cbosgd!crash, sdcsvax!crash, nosc!crash}!elgar!ag
[Gabryelski]  INET: ag@elgar.cts.com                 ARPA: elgar!ag@ucsd.edu

allbery@ncoast.UUCP (Brandon S. Allbery) (08/20/88)

As quoted from <16837@adm.ARPA> by rbj@nav.icst.nbs.gov (Root Boy Jim):
+---------------
| Just a side issue, but what if things change during your poking around in
| /dev/{kmem,swap}? How do ps-like programs deal with such things? 
+---------------

From the ps(1) manual:

"BUGS
"     Things can change while _ps_ is running; the picture it gives is only
"     a close approximation to reality."

I guess it doesn't.

++Brandon
-- 
Brandon S. Allbery, uunet!marque!ncoast!allbery			DELPHI: ALLBERY
	    For comp.sources.misc send mail to ncoast!sources-misc

bph@buengc.BU.EDU (Blair P. Houghton) (08/24/88)

In article <12266@ncoast.UUCP> allbery@ncoast.UUCP (Brandon S. Allbery) writes:
>As quoted from <16837@adm.ARPA> by rbj@nav.icst.nbs.gov (Root Boy Jim):
>+---------------
>| Just a side issue, but what if things change during your poking around in
>| /dev/{kmem,swap}? How do ps-like programs deal with such things? 
>+---------------
>
>From the ps(1) manual:
>
>"BUGS
>"     Things can change while _ps_ is running; the picture it gives is only
>"     a close approximation to reality."
>
>I guess it doesn't.

The proof:

Sometimes when running ps, the ps itself is listed; sometimes it's not.

Fascinating.

				--Blair