Re: Lost Process?
Re: Lost Process?
- Subject: Re: Lost Process?
- From: Terry Lambert <email@hidden>
- Date: Thu, 16 Mar 2006 16:42:19 -0800
On Mar 16, 2006, at 12:54 PM, Spencer Nielsen wrote:
I have an interesting problem that I am trying to understand.
I have a PreferencePane that uses code based off of Apple's GetPID
example (which in turn uses sysctl with CTL_KERN, KERN_PROC and
KERN_PROC_ALL) to query the state of currently running processes and
searches by name to see if a companion program is currently
running. My problem is that right now the results that the sysctl
call are not the same results displayed by top and Activity Monitor;
most notably that sysctl says that my companion program is currently
running, has a PID for it and everything but neither top nor
Activity Monitor say that it is.
These are really bad interfaces to use for this.
A more proper interface to use for this is to apriori know the pid.
This is normally done on UNIX systems by storing the in a file in the
directory /var/run. A program reads that file and gets the PID. It
then uses code like the following:
err = kill( pid, 0);
switch(err) {
case 0: /* exists, we have permission to kill */
case EPERM: /* exists, we don not have permission to kill */
...
break;
case ESRCH: /* process does not exist */
default: /* unexpected error - treat as not exists */
...
break;
}
If you need this information to find the process bundle, this is not
how you should do it, either. Instead, you should popen() the program
"/bin/ps" with appropriate arguments (specifically, use the '-o'
option to retrieve only the field you are interested in, and the '-p'
option to select a specific process ID, if desired. Throw away the
first line read fron the pipe, as that's the header. You may also
want to use the option '-ww' to avoid the 80/132 column output
restriction).
I'm not going to write sample code for that because I believe that
people should be discouraged from using this method, rather than
writing bundle information into /var/run file(s) as well (e.g. as the
second line, after the pid, or, if the pid is a known value, in a file
named "program.pid" in /var/run as a means of supporting multiple
instances of the program you are interested in (e.g. for support of a
licensed program inFast User Switching, or some other environment).
I have tried to sudo kill PID and nothing happens. sysctl always
reports back that the companion process is running. Up until now
sysctl would accurately report that my program is not running if it
is in fact not running and my PreferencePane would work as
intended. Because I have been working on developing the companion
program I have been launching and stopping it all over the place,
both through the debugger, the finder and otherwise. I had been
working on one portion of it for the last few days and have been
running the machine for a while and put it to sleep a few times. It
was not until I returned to working on the PreferencePane that I
noticed that it always said that my companion program was still
running even though top said that it was not. I started to debug
the PreferencePane to see if it was maybe some weird thing that I
missed. I isolated it down to the fact that sysctl is still
including a process structure for the companion program in the
results when as far as I understand, it shouldn't be.
I have also created a separate test program that simply calls sysctl
and looks for the same process. It also reports back that it is
running. I suspect that if I reboot my machine the problem will go
away or it will easily reproduce (which will then point me towards
the bug which is most likely mine). However, I am afraid that if I
do reboot that it will in fact go away and I will not be able to
reproduce the behavior (because I have no idea what behavior caused
it in the first place). Thus my opportunity to hunt this bug might
be gone for a while. I don't know much about how the kernel stores
process structures but possibilities that I have run through my head
are that something went wrong in the bsd process management of the
kernal (but then why does "top" not reflect the same results? does
top use sysctl or something else like mach calls?). Then again it
could also be random cosmic rays or my own bug that I am still
overlooking. So before I do actually reboot I wanted to throw it
out there and see if anybody more knowledgeable in these things than
me could provide any insight.
In general, the sysctl() interfaces you are attempting to use are
considered SPI - that means we may change them at any point, and that
you should use programs that use utilities that rev when the system
revs in order to obtain the information (for example, we guarantee
that the /bin/ps program will continue to work, no matter what we do
to the sysctl(0 interfaces it uses, or if we change it over to some
other interface, etc.).
Basically, this means you shouldn't use them.
That said, it's likely that your mistake is that you are not examining
the process state information from the first sysctl before calling
subsequent sysctl's, and therefore are not seeing some of the process
state flags that might indicate that the process has been zombied, or
that something else is going on (e.g. it's in the process of exiting,
etc.).
In general, this information is reported back in portable format from /
bin/ps, if you give it the appropriate '-o' option to select the
information you want back from it.
-- Terry
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden
References: | |
| >Lost Process? (From: Spencer Nielsen <email@hidden>) |