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