Skip to content

runtime: SIGPROF arriving on a foreign thread before any cgo call is made will crash the process #9456

@minux

Description

@minux

runtime.badsignal will try to deliver the signal received by foreign threads to sigqueue using the cgo callback mechanism, however, cgocallback will not work if the process has not made any cgo call yet.

A simple reproduction program:

package main

/*
#include <signal.h>
#include <pthread.h>
volatile int x;
static void *thread(void *p) {
    (void)p;
    while (x == 0)
        ;
    pthread_kill(pthread_self(), SIGPROF);
    return NULL;
}
__attribute__((constructor)) void test() {
    pthread_t tid;
    pthread_create(&tid, 0, thread, NULL);
}
*/
import "C"
import "sync/atomic"
import "unsafe"

func main() {
    atomic.StoreInt32((*int32)(unsafe.Pointer(&C.x)), 1)
    select {}
}

This example is contrived, but imagine the thread is created by an external library linked in, and the user is profiling Go code. See https://groups.google.com/forum/#!topic/golang-nuts/SMhWSUsfPag for a real-world example (the symptom is the same, and disabling the cgocallback line in function runtime.badsignal fixes it, but I'm still not sure about how the program could create the extra thread during benchmarking without any cgocall. The problem could also be in other part of runtime.)

Tentatively labeled 1.4.1, as there is no meaningful workaround for 1.4.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions