SIGCONT is not catchable?

770 views
Skip to first unread message

Paul Borman

unread,
Oct 15, 2011, 3:29:51 PM10/15/11
to golang-dev
It does not appear that SIGCONT is catchable.  in runtime/linux/signals.h I see:

        /* 18 */        0, "SIGCONT: continue",
        /* 19 */        0, "SIGSTOP: stop, unblockable",
        /* 20 */        Q+I+R, "SIGTSTP: keyboard stop",

If SIGTSP is catchable (and it should be) then SIGCONT should be as well so you can handle a process starting back up again.  For example, this code:

for s := range signal.Incoming {
    switch s.(os.UnixSignal) {
    case syscall.SIGINT:
        os.Exit(0)
    case syscall.SIGTSTP:
        fmt.Printf("\nStopping\n")
        syscall.Kill(0, syscall.SIGSTOP)
        fmt.Printf("\nStarting\n")
    default:
        fmt.Printf("Signal %s\n", s)
    }
}

produces:

^Z
Stopping

Starting
[1] + Stopped (SIGSTOP)        ./sig

You can't use syscall.Pause() to wait for the kill (that just pauses your signal handling thread forever).

Making SIGCONT catchable may require existing programs to need to be changed.  The signal interface should allow the application to express interest in which signals it handles.  I don't see anyway to do that, but it looks like a system specific method of updating runtime·sigtab[signum].flags would probably make this possible.

    -Paul

Kyle Lemons

unread,
Oct 15, 2011, 3:39:33 PM10/15/11
to Paul Borman, golang-dev
Making SIGCONT catchable may require existing programs to need to be changed.  The signal interface should allow the application to express interest in which signals it handles.  I don't see anyway to do that, but it looks like a system specific method of updating runtime·sigtab[signum].flags would probably make this possible.

I was under the impression that SIGKILL, SIGSTOP, and SIGCONT are handled outside the program and never make it to the binary.  (If I understand correctly, it's because they're job control signals and are handled by someone else.)  At least, this has been my experience with C binaries, and seemed to be the same in Go back when I put together a very similar ^Z/TSTP solution to what you posted.
~K 

Florian Weimer

unread,
Oct 15, 2011, 4:09:07 PM10/15/11
to Kyle Lemons, Paul Borman, golang-dev
* Kyle Lemons:

>>
>> Making SIGCONT catchable may require existing programs to need to be
>> changed. The signal interface should allow the application to express
>> interest in which signals it handles. I don't see anyway to do that, but it
>> looks like a system specific method of updating runtime·sigtab[signum].flags
>> would probably make this possible.
>>
>
> I was under the impression that SIGKILL, SIGSTOP, and SIGCONT are handled
> outside the program and never make it to the binary.

SIGCONT can be caught:

$ cat t.c
#include <signal.h>
#include <unistd.h>

void
handler(int i)
{
write(STDERR_FILENO, "hello\n", 6);
_exit(0);
}

int
main()
{
signal(SIGCONT, handler);
while (1) { }
}
$ gcc -Wall -O2 t.c
$ ./a.out
^Z
[1]+ Stopped ./a.out
fg
./a.out
hello
$

It seems that synchronous delivery of SIGTSTP is not guaranteed on
some systems, so catching SIGCONT is the only reliable way to redraw
the screen when a suspended process is put into the foreground again.

Kyle Lemons

unread,
Oct 15, 2011, 4:29:11 PM10/15/11
to Florian Weimer, Paul Borman, golang-dev
> I was under the impression that SIGKILL, SIGSTOP, and SIGCONT are handled
> outside the program and never make it to the binary.

SIGCONT can be caught:

Huh.  I stand corrected.  Sorry for the noise.  I went back and played around with some things and have come to the same conclusion as Paul. (w.r.t updating sigtab[SIGCONT].flags)

Paul Borman

unread,
Oct 15, 2011, 4:50:12 PM10/15/11
to golang-dev
Sigh.  More signal simplemindedness...

SIGQUIT is being handled directly by Go and is not returned vi signal.Incoming.  This is a a serious problem for programs more sophisticated programs.  There are good reasons that the UNIX signal handling model is not as simple as what Go is currently implementing.

I don't mind Go's runtime handling actual synchronous signals (because they are tied to the goroutine running at the tie), but all asynchronous signals should be able to be handled by the application (this should include someone sending a SIGFPE or SIGSEV from the outside, if possible.  On Linux this means if signfo_t.si_addr is NULL then the signal should be provided to the program and not handled by the runtime because the runtime is actually doing the wrong thing with it.)

I sympathize with the view that signals are not elegant, and I personally try to not use them as an IPC, but we are on machines where signals exist and we can't just ignore their existence.

Do you know how hard it is to teach people to not use ^\?

    -Paul

Russ Cox

unread,
Oct 17, 2011, 12:03:04 PM10/17/11
to Paul Borman, golang-dev
There is an open issue to redo the signal handling
so that you can ask for specific signals. Until that
happens, I would prefer to leave the existing code as is.
Its days are numbered.

Reply all
Reply to author
Forward
0 new messages