Commit fbe9724c by Ian Lance Taylor

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
parent f521b293
4d8e00e730897cc7e73b1582522ecab031cfcaf2 1d3e0ceee45012a1c3b4ff7f5119a72f90bfcf6a
The first line of this file holds the git revision number of the last The first line of this file holds the git revision number of the last
merge done from the gofrontend repository. merge done from the gofrontend repository.
...@@ -141,6 +141,15 @@ func freedefer(d *_defer) { ...@@ -141,6 +141,15 @@ func freedefer(d *_defer) {
if d.special { if d.special {
return 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() mp := acquirem()
pp := mp.p.ptr() pp := mp.p.ptr()
if len(pp.deferpool) == cap(pp.deferpool) { if len(pp.deferpool) == cap(pp.deferpool) {
......
...@@ -93,7 +93,7 @@ func initsig(preinit bool) { ...@@ -93,7 +93,7 @@ func initsig(preinit bool) {
} }
t.flags |= _SigHandling t.flags |= _SigHandling
setsig(i, funcPC(sigtramp), true) setsig(i, getSigtramp(), true)
} }
} }
...@@ -137,7 +137,7 @@ func sigenable(sig uint32) { ...@@ -137,7 +137,7 @@ func sigenable(sig uint32) {
if t.flags&_SigHandling == 0 { if t.flags&_SigHandling == 0 {
t.flags |= _SigHandling t.flags |= _SigHandling
fwdSig[sig] = getsig(int32(sig)) 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) { ...@@ -265,7 +265,7 @@ func raisebadsignal(sig int32, c *sigctxt) {
// We may receive another instance of the signal before we // We may receive another instance of the signal before we
// restore the Go handler, but that is not so bad: we know // restore the Go handler, but that is not so bad: we know
// that the Go program has been ignoring the signal. // that the Go program has been ignoring the signal.
setsig(sig, funcPC(sigtramp), true) setsig(sig, getSigtramp(), true)
} }
func crash() { func crash() {
......
...@@ -502,8 +502,8 @@ func goexit1() ...@@ -502,8 +502,8 @@ func goexit1()
func schedtrace(bool) func schedtrace(bool)
func freezetheworld() func freezetheworld()
// Signal trampoline, written in C. // Get signal trampoline, written in C.
func sigtramp() func getSigtramp() uintptr
// The sa_handler field is generally hidden in a union, so use C accessors. // The sa_handler field is generally hidden in a union, so use C accessors.
func getSigactionHandler(*_sigaction) uintptr func getSigactionHandler(*_sigaction) uintptr
......
...@@ -140,6 +140,15 @@ sigtramp(int sig, siginfo_t *info, void *context) ...@@ -140,6 +140,15 @@ sigtramp(int sig, siginfo_t *info, void *context)
#endif // USING_SPLIT_STACK #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 // C code to manage the sigaction sa_sigaction field, which is
// typically a union and so hard for mksysinfo.sh to handle. // typically a union and so hard for mksysinfo.sh to handle.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment