crosscall2documents an odd case: though it takes a fourth context argument, SWIG (for historical cases) calls it with only three arguments when calling _cgo_panic, leaving the context argument uninitialized.
Normally this is not an issue, as the context would not be used during a panic. However, some rare cases, such as a memory profiling sample in allocation, could trigger a stack trace. At this point, we'll pass the uninitialized context to the cgo traceback function (assuming runtime.SetCgoTraceback was called). This function may then crash or otherwise do something wrong with it.
This is easiest to reproduce by setting runtime.MemProfileRate = 1.
This is broken at least as far back as Go 1.16, but probably much longer.
The text was updated successfully, but these errors were encountered:
My test in https://golang.org/cl/345332 passes on 1.15 and bisection blames http://golang.org/cl/258938. That CL changed crosscall2 of _cgo_panic. Previously, crosscall2 directly called _cgo_panic, which explicitly called cgocallback with a nil ctxt. Afterwards, crosscall2 calls cgocallback directly, passing through the uninitialized ctxt.
@ianlancetaylor , that seems reasonable to me. Is there a reason SWIG can't just call panic from the Go code? Is it just that we really want to be able to use gostringnocopy rather than, say, C.GoString, which does a heap allocation?
Yeah, I've thought about this more, and I think SWIG should just do it all itself.
My hesitation there is that it's hard to avoid adding this exported function to every SWIG generated file, and since it is exported it will be kept in the binary. The result for a program that uses SWIG for several different libraries is duplication of the panic code. But it may be possible to only emit the exported function if the code actually calls _swig_gopanic. It's not trivial because there are many different ways that SWIG can call that function.
OK, SWIG versions newer than 4.1.0 no longer call crosscall2.
I'm going to close this issue: the problem is really that SWIG was using an undocumented and unsupported API, and people who encounter the problem described here can now upgrade to a newer version of SWIG.