You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is the general case of issue #15994, which focused on SIGPROF.
A somewhat unlikely deadlock is possible when an asynchronous signal occurs on a C thread. Here a C thread means a thread started by calling pthread_create or equivalent. This will lead to a series of calls:
cgoSigtramp
sigtramp
sigtrampgo
sigfwdgo (which will return false if there is no C signal handler)
badsignal
cgocallback
badsignalgo
The call to cgocallback may cause the Go runtime to wait for a thread to be available to run badsignalgo in a goroutine. In some case this may cause the runtime to start a new thread. Starting a new thread in a cgo-using program means calling _cgo_thread_start, which calls malloc.
In other words, we've called malloc in a signal handler, which is not a good idea. If the asynchronous signal occurred while the C thread was itself running malloc, the whole program can deadlock at this point.
We may be able to fix this by simply removing the call to cgocallback. It was introduced in https://golang.org/cl/10757044, but with the knowledge that we are running on the system stack, and some care, it may be possible to avoid it.
The text was updated successfully, but these errors were encountered:
Ping @ianlancetaylor. Is this still a problem? needm no longer creates threads itself (I think it used to, but I may be mis-remembering). Or is there still a danger that it may wait forever for another thread to create a thread for it if that other thread is blocked on malloc?
I believe this can still happen. The problem is not that needm creates the thread itself, but that it blocks waiting for a thread to be created, in lockextra. That block may be happening while running a signal handler for a signal that may have been delivered while executing the C malloc function, meaning that we are blocking while malloc is holding locks. Eventually the Go runtime will create a new thread, but in a cgo program that means calling the C malloc function, so thread creation blocks waiting for the malloc lock to be released. At that point we are deadlocked.
I'm going to reverse myself. I think that this is no longer a problem. We stopped calling cgocallback in https://golang.org/cl/30218. The current code only calls needm. I was wrong to say that needm blocks waiting for a thread to be created; it only blocks waiting for an m to be allocated, and, as you observe, that does not require creating a thread.
This is the general case of issue #15994, which focused on
SIGPROF
.A somewhat unlikely deadlock is possible when an asynchronous signal occurs on a C thread. Here a C thread means a thread started by calling
pthread_create
or equivalent. This will lead to a series of calls:The call to
cgocallback
may cause the Go runtime to wait for a thread to be available to runbadsignalgo
in a goroutine. In some case this may cause the runtime to start a new thread. Starting a new thread in a cgo-using program means calling_cgo_thread_start
, which callsmalloc
.In other words, we've called
malloc
in a signal handler, which is not a good idea. If the asynchronous signal occurred while the C thread was itself runningmalloc
, the whole program can deadlock at this point.We may be able to fix this by simply removing the call to
cgocallback
. It was introduced in https://golang.org/cl/10757044, but with the knowledge that we are running on the system stack, and some care, it may be possible to avoid it.The text was updated successfully, but these errors were encountered: