Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 6 Feb 2003 13:24:16 +0200
From:      Andrey Simonenko <simon@comsys.ntu-kpi.kiev.ua>
To:        freebsd-hackers@freebsd.org
Subject:   Help with understanding process state, context switching and signals
Message-ID:  <20030206112416.GA133@pm514-9.comsys.ntu-kpi.kiev.ua>

next in thread | raw e-mail | index | archive | help
Hello.

After spending some time in reading different mailing lists archives,
analyzing FreeBSD 4.x sys/kern and sys/i386 sources and reading 4.4BSD book
I still can't find an answer, so, I ask my question here.

In short: I need to stop (suspend) some process from the kernel, when
that process is in user mode and get information about its general-purpose
registers, its VM structures, etc.  The quick answer is following: "Send
SIGSTOP to that process and do what you want", but this doesn't help me.

I wrote a module for some pseudo device, which allows me to enter to
the system via ioctl() syscall.  Next, I need to determine when target
process *p is in user mode, I suppose that following code is correct:

	s = splhigh();
	if (p->p_stat == SRUN)
		in_user_mode = 1;
	splx(s);

because only one process can enter the kernel at a time.
Am I correct here?

Next, when I determine that target process is in user mode I have to
stop (or suspend) it.  As I understand I can't simply remove a process
from the run queue, because the kernel should save the current execution
state of a process in process's PCB.  I suppose that it is possible to
simply remove a process from the run queue if there is only one CPU,
because 4.4BSD kernel is never preempted to run another process, while
executing in a system call (until current executing process force voluntary
context switching).  But such approach does not work on the system with
several CPU.

Am I right about system with one CPU and about system with several CPU?

First my idea was to call psignal(p, SIGSTOP).  But a signal will be
delivered to a target process asynchronously with respect to the current
process.  That is, following code _is not_ correct:

	psignal(p, SIGSTOP);
	/* From this line process *p is stopped. Is it correct? */

So, I need to stay in loop and checking p->p_stat == SSTOP.  But this is
not correct because current process will get all CPU time.  If current
process relinquishes the processor, then target process will have a chance
to get a signal (in case with the system with one CPU at least).  If current
executing process relinquishes the CPU, then target process has a chance to
enter the kernel.  The kernel checks if there are any pending signals each
time when a process enters the system (in syscall), and if there is SIGSTOP,
then a process will be stopped immediately.  That is I need another
loop which will test if stopped target process was stopped in user mode
(probably compare last Assembler instruction of a process with int 0x80
instruction).

Where am I wrong in my reasoning?

Is there another (or correct) way to suspend some process when it is
in user mode?  The problem actually not in suspending (we have SIGSTOP),
but in synchronization as I understand.

Please help me with understanding all this.

I have another questions, but I think I misunderstood something in
process state, context switching and delivering a signal.

Thanks.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030206112416.GA133>