runtime: fixes for -buildmode=c-archive
With -buildmode=c-archive, initsig is called before the memory allocator has been initialized. The code was doing a memory allocation because of the call to funcPC(sigtramp). When escape analysis is fully implemented, that call should not allocate. For now, finesse the issue by calling a C function to get the C function pointer value of sigtramp. When returning from a call from C to a Go function, a deferred function is run to go back to syscall mode. When the call occurs on a non-Go thread, that call sets g to nil, making it impossible to add the _defer struct back to the pool. Just drop it and let the garbage collector clean it up. Reviewed-on: https://go-review.googlesource.com/33675 From-SVN: r242992
This commit is contained in:
parent
f521b29334
commit
fbe9724cc3
@ -1,4 +1,4 @@
|
||||
4d8e00e730897cc7e73b1582522ecab031cfcaf2
|
||||
1d3e0ceee45012a1c3b4ff7f5119a72f90bfcf6a
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
@ -141,6 +141,15 @@ func freedefer(d *_defer) {
|
||||
if d.special {
|
||||
return
|
||||
}
|
||||
|
||||
// When C code calls a Go function on a non-Go thread, the
|
||||
// deferred call to cgocallBackDone will set g to nil.
|
||||
// Don't crash trying to put d on the free list; just let it
|
||||
// be garbage collected.
|
||||
if getg() == nil {
|
||||
return
|
||||
}
|
||||
|
||||
mp := acquirem()
|
||||
pp := mp.p.ptr()
|
||||
if len(pp.deferpool) == cap(pp.deferpool) {
|
||||
|
@ -93,7 +93,7 @@ func initsig(preinit bool) {
|
||||
}
|
||||
|
||||
t.flags |= _SigHandling
|
||||
setsig(i, funcPC(sigtramp), true)
|
||||
setsig(i, getSigtramp(), true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,7 +137,7 @@ func sigenable(sig uint32) {
|
||||
if t.flags&_SigHandling == 0 {
|
||||
t.flags |= _SigHandling
|
||||
fwdSig[sig] = getsig(int32(sig))
|
||||
setsig(int32(sig), funcPC(sigtramp), true)
|
||||
setsig(int32(sig), getSigtramp(), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -265,7 +265,7 @@ func raisebadsignal(sig int32, c *sigctxt) {
|
||||
// We may receive another instance of the signal before we
|
||||
// restore the Go handler, but that is not so bad: we know
|
||||
// that the Go program has been ignoring the signal.
|
||||
setsig(sig, funcPC(sigtramp), true)
|
||||
setsig(sig, getSigtramp(), true)
|
||||
}
|
||||
|
||||
func crash() {
|
||||
|
@ -502,8 +502,8 @@ func goexit1()
|
||||
func schedtrace(bool)
|
||||
func freezetheworld()
|
||||
|
||||
// Signal trampoline, written in C.
|
||||
func sigtramp()
|
||||
// Get signal trampoline, written in C.
|
||||
func getSigtramp() uintptr
|
||||
|
||||
// The sa_handler field is generally hidden in a union, so use C accessors.
|
||||
func getSigactionHandler(*_sigaction) uintptr
|
||||
|
@ -140,6 +140,15 @@ sigtramp(int sig, siginfo_t *info, void *context)
|
||||
|
||||
#endif // USING_SPLIT_STACK
|
||||
|
||||
// C function to return the address of the sigtramp function.
|
||||
uintptr getSigtramp(void) __asm__ (GOSYM_PREFIX "runtime.getSigtramp");
|
||||
|
||||
uintptr
|
||||
getSigtramp()
|
||||
{
|
||||
return (uintptr)(void*)sigtramp;
|
||||
}
|
||||
|
||||
// C code to manage the sigaction sa_sigaction field, which is
|
||||
// typically a union and so hard for mksysinfo.sh to handle.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user