Thursday, March 26, 2009

Trying too hard

From time to time I can see people trying to be too clever about some problems. What I mean by that is that sometimes they try too hard to use latest technologies to do something while there is already a solution which does the job. Or sometimes instead of taking a step back and taking a deep breath they dive directly into problem solving coming up with crazy ways to accomplish something. I guess it happens to all of us from time to time. This time it happened to me :) :)

A colleague approached me with a problem he had on some old Solaris 7 server which is stripped and customized and there is no pargs command there. He needed to get a full argument list of a running process but ps truncate it to 80 characters. Well I thought a simple C program should be able to extract the information via /proc. So me trying to be helpful I started to write it right a way. After some time I came up with:

bash-2.05# cat pargs.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <procfs.h>
#include <sys/procfs.h>
#include <sys/prsystm.h>

int main(int argc, char *argv[])
psinfo_t p;
char *file;
int fd;
int fd_as;
uintptr_t pargv[1024];
char arg[1024];
int i;

if(argc != 3)
printf("Usage: %s /proc/PID/psinfo\n", argv[0]);

file = argv[1];
fd = open(file, O_RDONLY);
if (fd == -1)
printf("Can't open %s file\n", file);

read(fd, &p, sizeof(p));

fd_as = open(argv[2], O_RDONLY);

printf("nlwp: %d\n", p.pr_nlwp);
printf("exec: %s\n", p.pr_fname);
printf("args: %s\n", p.pr_psargs);
printf("argc: %d\n", p.pr_argc);

pread(fd_as, &pargv, p.pr_argc * sizeof (uintptr_t), p.pr_argv);
for (i=0; i<p.pr_argc; i++)
pread(fd_as, &arg, 256, ((uintptr_t *)pargv)[i]);
printf(" %s\n", arg);


Job done.
Well couple of minutes later I realized that UCB version of ps is able to show long argument list...

bash-2.05# /usr/ucb/ps -axuww |grep "19179"
XXXX 19179 9.3 2.23998422056 ? S 11:02:30 0:02 /usr/java/bin/../bin/sparc/native_threads/java -classpath :./classes/packages/jakarta-regexp-1.3.jar:./classes/packages/ MailSender

I had a good laugh at myself.


James said...

Unrelated, but have you seen the discussion about AutoInstall vs Jumpstart on desktop-discuss? (No idea why it's on that list and not say caiman-discuss).

Anonymous said...

This approach does have some uses though. It inspired be to replace this section of script:

pgrep -z $zone | xargs -i /usr/ucb/ps -auxww {} | grep -v USER

with this:

pgrep -z $zone | xargs /tmp/procargs

(procargs being a C program)

which runs 10x faster.