• Alan Donovan's avatar
    runtime: discard SIGPROF delivered to non-Go threads. · 532dee38
    Alan Donovan authored
    Signal handlers are global resources but many language
    environments (Go, C++ at Google, etc) assume they have sole
    ownership of a particular handler.  Signal handlers in
    mixed-language applications must therefore be robust against
    unexpected delivery of certain signals, such as SIGPROF.
    
    The default Go signal handler runtime·sigtramp assumes that it
    will never be called on a non-Go thread, but this assumption
    is violated by when linking in C++ code that spawns threads.
    Specifically, the handler asserts the thread has an associated
    "m" (Go scheduler).
    
    This CL is a very simple workaround: discard SIGPROF delivered to non-Go threads.  runtime.badsignal(int32) now receives the signal number; if it returns without panicking (e.g. sig==SIGPROF) the signal is discarded.
    
    I don't think there is any really satisfactory solution to the
    problem of signal-based profiling in a mixed-language
    application.  It's not only the issue of handler clobbering,
    but also that a C++ SIGPROF handler called in a Go thread
    can't unwind the Go stack (and vice versa).  The best we can
    hope for is not crashing.
    
    Note:
    - I've ported this to all POSIX platforms, except ARM-linux which already ignores unexpected signals on m-less threads.
    - I've avoided tail-calling runtime.badsignal because AFAICT the 6a/6l don't support it.
    - I've avoided hoisting 'push sig' (common to both function calls) because it makes the code harder to read.
    - Fixed an (apparently incorrect?) docstring.
    
    R=iant, rsc, minux.ma
    CC=golang-dev
    https://golang.org/cl/6498057
    532dee38
signal_linux_amd64.c 3.88 KB