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>