golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.19k stars 17.57k forks source link

runtime: misleading panic information when an unexpected signal is received running signal handler #46286

Open pmur opened 3 years ago

pmur commented 3 years ago

I have a hard time classifying whether this is a bug or not. When a signal handler causes an unexpected fault, the runtime will push a stack frame onto the signal stack, and runtime.sigpanic will panic again when the stack check fails. On ppc64le this results in confusing debug information being printed, i.e fatal: morestack on g0. This happens in cockroachdb on ppc64le when backtrace segfaults as it unwinds past the kernel's interrupt frame.

What version of Go are you using (go version)?

$ go version
go version devel go1.17-69fb3c8bd1 Wed May 12 11:20:32 2021 -0500 linux/ppc64le

Does this issue reproduce with the latest release?

Yes, and 1.16.x series.

What operating system and processor architecture are you using (go env)?

ppc64le

What did you do?

package main

// #include <signal.h>
// #include <unistd.h>
// #include <string.h>
// static void* buf[100];
//
// void handle(int sig, siginfo_t *i, void *ctx) {
//    *((int*)1) = sig;
// }
// 
// void segfault(void) {
//  struct sigaction a;
//  memset(&a, 0, sizeof(a));
//  a.sa_sigaction = handle;
//  a.sa_flags = SA_ONSTACK | SA_RESTART | SA_SIGINFO;
//  sigaction(SIGALRM, &a, NULL);
//  alarm(1);
// }
import "C"

import (
        "fmt"
        "math/rand"
        "sync"
)

func main() {
        var bigthing [200]int;
        for i,_ := range bigthing {
                bigthing[i] = rand.Int()
        }
        C.segfault()
        m := sync.Mutex{}
        m.Lock()
        cond := sync.NewCond(&m)

        // Intentional deadlock here.
        cond.Wait()

        fmt.Printf("FAIL %v\n", bigthing)
}

What did you expect to see?

A crash without fatal: morestack on g0. For extra credit, also showing that handler is where the crash happened.

What did you see instead?

fatal: morestack on g0
SIGSEGV: segmentation violation
PC=0x10063c20 m=0 sigcode=1

goroutine 0 [idle]:
runtime.abort()
    /home/murp/git/go/src/runtime/asm_ppc64x.s:795
runtime.morestack()
    /home/murp/git/go/src/runtime/asm_ppc64x.s:300 +0x18

goroutine 1 [sync.Cond.Wait]:
sync.runtime_notifyListWait(0xc0001ee050, 0x0)
    /home/murp/git/go/src/runtime/sema.go:513 +0x174
sync.(*Cond).Wait(0xc0001ee040)
    /home/murp/git/go/src/sync/cond.go:56 +0xd4
main.main()
    /home/murp/test/cgo-segfault/foo.go:47 +0x134

r0   0x0    r1   0xc000008f60
r2   0xc000290000   r3   0x17
r4   0x100a683f r5   0x17
r6   0xc000009000   r7   0x10149c60
r8   0x10149ac0 r9   0x0
r10  0x0    r11  0x0
r12  0x0    r13  0x7fff9999a7c0
r14  0x5    r15  0x5
r16  0x1014a078 r17  0x3000
r18  0x100bfdb5 r19  0x0
r20  0xc000032e28   r21  0x10149c60
r22  0x0    r23  0x8
r24  0x0    r25  0x0
r26  0x10063cc4 r27  0x0
r28  0x101108b0 r29  0x7fff9998f1a8
r30  0x10149ac0 r31  0x10061674
pc   0x10063c20 ctr  0x0
link 0x10061678 xer  0x0
ccr  0x42420844 trap 0x300
ianlancetaylor commented 3 years ago

I think this is definitely a bug. It might be hard to fix.