I am often looking for a command whos args are many and exceed the 80
char width limitation in the 'ps -o args' or ps -f.
I found a blog that talks about
/usr/include/sys/user.h
there is a #define PSARGSZ 80
in there that could supposedly be changed to something wider (i tried
254)
then I relinked the kernel (and rebooted - for those who might think
I'm stupid)
but - ps -o args, and ps -f, still truncate the 'args' portion of the
listing to 80 chars.
any suggestions?
any one know of a different command (maybe one of the gnu utils) to
list processes?
anyone know how to get the OS to consider /usr/include/sys and rebuild
the ps command?
any ideas at all?
(I do have the full development system as well as the full gnu-tools
5.07Kj as well
as gwxlibs200Eb).
thx
You aren't going to be able to reach this goal. All parts of the OSR5
kernel are built with the original version of the <sys/user.h> that you
see in your /usr/include hierarchy. You do not have sources to rebuild
the whole kernel. Relinking the kernel uses pre-compiled objects.
I happen to know that if you _did_ have kernel sources and made the
proposed change, (1) the resulting kernel wouldn't boot; (2) if it did,
`ps` would no longer be able to make any sense at all out of it (it
wouldn't work at all); (3) all sorts of other parts of the system would
also fail. The structure you're trying to modify is referenced by
kernel- and user-level code all over the system, much of it precompiled
and insensitive to changes in the headers on your filesystem.
Changing that field would require moving it into a different structure
so that the structure offsets of `struct user' remained unchanged.
Users of that field (such as `ps`) would then have to be modified to
look for it in the new location.
>Bela<
again, thx
sam
Please copy enough context so people know what you're replying to.
You don't seem to understand. The information you're looking for
_isn't_ reliably stored anywhere. That is, it's stored in the user
struct, in `char u_psargs[PSARGSZ]', where PSARGSZ is equal to 80. When
a new program is started with an exec() system call, the kernel passes
the entire argument list to the new process. It also keeps a copy of it
for future reference. That copy is u_psargs[], and is limited to 80
chars. If the total arguments were longer than that -- too bad. The
kernel doesn't keep it. There is no utility that can retrieve it
because it doesn't exist.
Now, there are a number of objections that can be made to what I just
said. Depending on how a process was started and how it behaves, there
_are_ several places this information could be retrieved from. The
problem is that these other places are unreliable and hard to reach.
If it was started by a caller which waits for it (fork-exec-wait),
chances are good that you can find the called program's arguments
somewhere on the calling program's stack. But this is very difficult to
pull off, and cannot be reliable.
If a process was started from an interactive shell that keeps a history
(all but `sh`), the command line is stored in that shell's memory and
probably in a history file on disk. But there is nothing to tell you
which history line in which file corresponds to which running process.
When the kernel passes a process's arguments to it, they live at a
particular place in that process's address space. _If_ the process is
cooperative and doesn't overwrite those passed-in arguments, you could
possibly retrieve them. A program could be written to do this and I
expect it would have a more or less acceptable success rate. Nothing
like 100%, but in a typical system you might get to see the full command
lines of 70-90% of processes. However, since you would be retrieving
the arguments from process memory, you would have no way to confirming
that they are unmodified. (You could compare the first up-to-80 chars
to the contents of u_psargs[]; then the only untrustworthy parts would
be the part of each process's args extending past 80 chars; net result:
exactly the same as now, plus untrustable additional data.)
That said, a program that dug up process' args from the startup stack
_would_ be interesting... Somewhat better than nothing, anyway.
>Bela<
setproctitle() lets even ordinary-user processes replace all but the
command-name itself in u_psargs, so ps -f output is hardly inviolate.
And, heck, the process' own argument vector is where some other *nix flavors
(Linux, BSD) *always* get that information from:
main(int argc, char *argv[])
{
argv[1][0] = 'z';
sleep(10);
}
$ ./t test & ps -f -p$!
UID PID PPID C STIME TTY TIME CMD
spcecdt 5469 4109 0 08:30 pts/2 00:00:00 ./t zest
JOhn
--
John DuBois spc...@armory.com KC6QKZ/AE http://www.armory.com/~spcecdt/
Sure, but this is done with considerable kernel help; or at least on
Linux it is:
$ xxd -g1 /proc/self/cmdline
0000000: 78 78 64 00 2d 67 31 00 2f 70 72 6f 63 2f 73 65 xxd.-g1./proc/se
0000010: 6c 66 2f 63 6d 64 6c 69 6e 65 00 lf/cmdline.
$ xxd -g1 /proc/1/cmdline
0000000: 69 6e 69 74 20 5b 33 5d 00 00 init [3]..
To do the same on OpenServer, the `ps` command-equivalent would have to
ptrace(S) every process on the system in order to grub around in its
memory; or it would have to get pretty funky with kernel scraping. I
would choose the kernel scraping route (less invasive, less likely to
cause other processes to die or behave weirdly).
>Bela<
>they live at a
>particular place in that process's address space. _If_ the process is
>cooperative and doesn't overwrite those passed-in arguments, you could
>possibly retrieve them. A program could be written to do this and I
>expect it would have a more or less acceptable success rate.
would love to see the small piece of the program that knows to do this.
sam
My point was just that this has always been treated as a reasonable a way to
get that information, even though processes can modify the information.
I remember being surprised at the way XENIX did it (and its limitations),
having been accustomed to the BSD method.
John
do you have any sample code that, given a process, can discover the
address space (/dev/mem or /dev/kmem) and obtain the args to a process?
thx
I'm wondering if possibby you are asking the wrong question?
If this is just any old process, then yeah, you unfortunately want what
has been discussed here.
But by any chance is it some specific command or process that you want
this for? If so, I can think of all sorts of ways to provide that; the
most obviious being to replace the binary with one that conveniently
stores its arguments (and whatever else you'd like to know) somewhere
for your perusal and then execs the original binary.
Would that solve your problem?
It may not answer this person's need, but it might be a simple solution
for somebody.