Subject: stopping childs (patch included)
To: None <tech-kern@netbsd.org>
From: Emmanuel Dreyfus <manu@netbsd.org>
List: tech-kern
Date: 11/02/2002 00:45:04
Hi all
I frequently have the need to stop a process on fork or exec, for debugging
purposes. It can be done by tricking the process into an infinite loop, or by
adding somes hacks in the kernel to send a SIGSTOP at the right time.
Some support in the kernel to do this would be nice. My idea is to use a sysctl
to set a value (named p_stopchild) stored in struct proc:
$ sysctl -w proc.$$.stopchild=2
proc.291.stopchild: 0 -> 2
$ ls
Here, the shell gets blocked after the fork. It's possible to attach it, or to
send a SIGCONT. Once the process can continue after the fork, p_stopchild is
decreased. Because it does not reach zero, we will stop again after the shell
calls exec to become ls.
Find below a patch that does the job. Is it good enough to be committed?
Index: sys/proc.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/proc.h,v
retrieving revision 1.147
diff -r1.147 proc.h
189a190
> int p_stopchild; /* Stop childs on fork and exec */
Index: sys/sysctl.h
===================================================================
RCS file: /cvsroot/syssrc/sys/sys/sysctl.h,v
retrieving revision 1.78
diff -r1.78 sysctl.h
593c593,594
< #define PROC_PID_MAXID 3
---
> #define PROC_PID_STOPCHILD 3
> #define PROC_PID_MAXID 4
598a600
> { "stopchild", CTLTYPE_INT }, \
Index: kern/kern_sysctl.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_sysctl.c,v
retrieving revision 1.113
diff -r1.113 kern_sysctl.c
746a747,753
> if (name[1] == PROC_PID_STOPCHILD) {
> if (namelen != 2)
> return EINVAL;
> error = sysctl_int(oldp, oldlenp, newp,
> newlen, &ptmp->p_stopchild);
> return error;
> }
Index: kern/kern_exec.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_exec.c,v
retrieving revision 1.160
diff -r1.160 kern_exec.c
740a741,753
>
> if (p->p_stopchild) {
> int s;
>
> sigminusset(&contsigmask, &p->p_sigctx.ps_siglist);
> SCHED_LOCK(s);
> p->p_stopchild--;
> p->p_stat = SSTOP;
> mi_switch(p, NULL);
> SCHED_ASSERT_UNLOCKED();
> splx(s);
> }
>
Index: kern/kern_fork.c
===================================================================
RCS file: /cvsroot/syssrc/sys/kern/kern_fork.c,v
retrieving revision 1.96
diff -r1.96 kern_fork.c
474c474,475
< * Make child runnable, set start time, and add to run queue.
---
> * Make child runnable, set start time, and add to run queue
> * except if the parent requested the child to start in SSTOP state.
479,480c480,487
< p2->p_stat = SRUN;
< setrunqueue(p2);
---
> if (p1->p_stopchild) {
> p2->p_stat = SSTOP;
> p2->p_stopchild = p1->p_stopchild - 1;
> p1->p_stopchild = 0;
> } else {
> p2->p_stat = SRUN;
> setrunqueue(p2);
> }
--
Emmanuel Dreyfus.
"Le 80x86 n'est pas si complexe - il n'a simplement pas de sens"
(Mike Johnson, responsable de la conception x86 chez AMD)
manu@netbsd.org