runtime: don't crash if signal handler info argument is nil
authorIan Lance Taylor <ian@gcc.gnu.org>
Mon, 14 Nov 2016 23:16:04 +0000 (23:16 +0000)
committerIan Lance Taylor <ian@gcc.gnu.org>
Mon, 14 Nov 2016 23:16:04 +0000 (23:16 +0000)
    Apparently on Solaris 10 a SA_SIGINFO signal handler can be invoked with
    a nil info argument.  I would not have believed it but I've now seen it
    happen, and the sigaction man page actually says "If the second argument
    is not equal to NULL, it points to a siginfo_t structure...."  So, if
    that happens, don't crash.

    Also fix another case where we want to make sure that &T{} does not
    allocate.

    Reviewed-on: https://go-review.googlesource.com/33150

From-SVN: r242403

gcc/go/gofrontend/MERGE
libgo/go/runtime/signal_gccgo.go
libgo/go/runtime/signal_sigtramp.go
libgo/runtime/go-signal.c

index 9634f00..1fe9dec 100644 (file)
@@ -1,4 +1,4 @@
-3c8d91cff0ad3d233ebd268f88a3749d38a0aac1
+eb716b515356166d3177e6244619be5901f31162
 
 The first line of this file holds the git revision number of the last
 merge done from the gofrontend repository.
index 0ecafcc..321c619 100644 (file)
@@ -47,7 +47,14 @@ type sigctxt struct {
        ctxt unsafe.Pointer
 }
 
-func (c *sigctxt) sigcode() uint64 { return uint64(c.info.si_code) }
+func (c *sigctxt) sigcode() uint64 {
+       if c.info == nil {
+               // This can happen on Solaris 10.  We don't know the
+               // code, just avoid a misleading value.
+               return _SI_USER + 1
+       }
+       return uint64(c.info.si_code)
+}
 
 //go:nosplit
 func sigblock() {
index 67b9e67..667d5fe 100644 (file)
@@ -29,7 +29,8 @@ func sigtrampgo(sig uint32, info *_siginfo_t, ctx unsafe.Pointer) {
                        // get here anyhow.
                        return
                }
-               badsignal(uintptr(sig), &sigctxt{info, ctx})
+               c := sigctxt{info, ctx}
+               badsignal(uintptr(sig), &c)
                return
        }
 
index 9ee02a3..b844dc5 100644 (file)
@@ -187,7 +187,11 @@ getSiginfo(siginfo_t *info, void *context __attribute__((unused)))
        Location loc[1];
        int32 n;
 
-       ret.sigaddr = (uintptr)(info->si_addr);
+       if (info == nil) {
+               ret.sigaddr = 0;
+       } else {
+               ret.sigaddr = (uintptr)(info->si_addr);
+       }
        ret.sigpc = 0;
 
        // There doesn't seem to be a portable way to get the PC.