I wanted to get some process information, so I first wrote
a program just to test if I was doing things correctly. The program
is below. It takes one argument on the command line (a process number)
and opens /proc/that-process-number, then does a PIOCPSINFO ioctl to
get some information. Then I try to print that processes argv[].
I am running Solaris 2.5 on a sparc 10 (dual cpu). I'm using
gcc version 2.7.1.
My test was to start a "sleep 10000" in the background, and then
use its process ID, to test. My program is named 'testing'. i.e.,
FIRST TEST
example% gcc -g testing.c -o testing
example% sleep 10000 &
[1] 1048
example% ./testing 1048
arglist: ./testing 1048
example%
I get the arglist of the executing program printed. Then, I su
to root, and do it again:
SECOND TEST
example# ./testing 1048
Segmentation Fault (core dumped)
example#
THIRD TEST (regular user, under gdb)
example% gdb ./testing
[GNU BABBLING MESSAGES REMOVED]
(gdb) run 1048
Starting program: /usr/local/home/andrew/c/proc/./testing 1048
arglist: HZ=100 LD_LIBRARY_PATH=/usr/lib:/usr/openwin/lib
What gives? I'm pretty certain I'm doing something very wrong, but
what is it?
Thanks,
Andrew Benson (and...@arbitrade.com)
--
REDISTRIBUTION OF THIS WORK BY THE MICROSOFT NETWORK IS STRICTLY PROHIBITED
I forgot to include the program (Thanks Kevin Thomas for pointing
that out to me). Here it is:
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/signal.h>
#include <sys/fault.h>
#include <sys/syscall.h>
#include <sys/procfs.h>
#include <sys/stat.h>
#include <fcntl.h>
int main(int argc, char **argv)
{
char procname[1024];
prpsinfo_t p;
int fd;
int i;
/* Open process */
sprintf(procname, "/proc/%d", atol(argv[1]));
if ((fd = open(procname, O_RDWR)) == -1) {
perror(procname);
exit(1);
}
/* Get process summary info */
if (ioctl(fd, PIOCPSINFO, (void *)&p) == -1) {
perror("PIOCPSINFO");
exit(2);
}
/* Print argv[] of process */
for(i=0; i < p.pr_argc; ++i)
printf("%s%s%s", i ? " ": "arglist: ", p.pr_argv[i],
((i+1) == p.pr_argc) ? "\n" : "" );
close(fd);
exit(0);
}
> sprintf(procname, "/proc/%d", atol(argv[1]));
Style (and future portability nit): you're printing a long as an int.
Why not:
sprintf(procname, "/proc/%s", argv[1]);
> /* Print argv[] of process */
> for(i=0; i < p.pr_argc; ++i)
> printf("%s%s%s", i ? " ": "arglist: ", p.pr_argv[i],
> ((i+1) == p.pr_argc) ? "\n" : "" );
> close(fd);
> exit(0);
These pointers are relative to the traced processes address space.
You'll need to retrieve them with lseek/read from the fd you just
opened. The pointers supplied just tell you where the arguments are
in the examined process.
Casper
--
Casper Dik - Sun Microsystems - via my guest account at the University
of Amsterdam. My work e-mail address is: Caspe...@Holland.Sun.COM
Statements on Sun products included here are not gospel and may
be fiction rather than truth.