Subject: Re: stopping childs (patch included)
To: None <tech-kern@netbsd.org>
From: Christos Zoulas <christos@zoulas.com>
List: tech-kern
Date: 11/01/2002 23:58:11
In article <1fkzwc9.7vsinfdyha5iM@[10.0.12.137]>,
Emmanuel Dreyfus <manu@netbsd.org> wrote:
I like it. You can use a short for the value, and stuff it in the space
of pad1[];
christos
>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