1
0
mirror of https://github.com/golang/go synced 2024-11-26 01:17:57 -07:00

test: trigger SIGSEGV instead of SIGTRAP in issue11656.go

In issue11656.go, it tests that if the runtime can get a
reasonable traceback when it faults at a non-function PC. It does
it by jumping to an address that contains an illegal or trap
instruction. When it traps, the SIGTRAP crashes the runtime.

This CL changes it to use an instruction that triggers SIGSEGV.
This is due to two reasons:
- currently, the handling of bad PC is done by preparePanic,
  which is only used for a panicking signal (SIGSEGV, SIGBUS,
  SIGFPE), not a fatal signal (e.g. SIGTRAP).
- the test uses defer+recover to get a traceback, which only
  works for panicking signals, not fatal signals.

Ideally, we should handle all kinds of faults (SIGSEGV, SIGBUS,
SIGILL, SIGTRAP, etc.) with a nice traceback. I'll leave this
for the future.

This CL also adds RISCV64 support.

Fixes #43283.

Change-Id: I5e0fbf8530cc89d16e05c3257d282bc1d4d03405
Reviewed-on: https://go-review.googlesource.com/c/go/+/279423
Trust: Cherry Zhang <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
This commit is contained in:
Cherry Zhang 2020-12-21 18:41:16 -05:00
parent 0aa9b4709a
commit c06a354bcc

View File

@ -27,13 +27,6 @@ import (
)
func main() {
// This test is currently failing on some architectures.
// See issue #43283.
switch runtime.GOARCH {
case "ppc64", "mips", "mipsle", "mips64", "mips64le":
return
}
debug.SetPanicOnFault(true)
defer func() {
if err := recover(); err == nil {
@ -61,27 +54,30 @@ func f(n int) {
x uintptr
}
// We want to force an illegal instruction, to get a crash
// at a PC value != 0.
// We want to force a seg fault, to get a crash at a PC value != 0.
// Not all systems make the data section non-executable.
ill := make([]byte, 64)
switch runtime.GOARCH {
case "386", "amd64":
binary.LittleEndian.PutUint16(ill, 0x0b0f) // ud2
ill = append(ill, 0x89, 0x04, 0x25, 0x00, 0x00, 0x00, 0x00) // MOVL AX, 0
case "arm":
binary.LittleEndian.PutUint32(ill, 0xe7f000f0) // no name, but permanently undefined
binary.LittleEndian.PutUint32(ill, 0xe3a00000) // MOVW $0, R0
binary.LittleEndian.PutUint32(ill, 0xe5800000) // MOVW R0, (R0)
case "arm64":
binary.LittleEndian.PutUint32(ill, 0xd4207d00) // brk #1000
binary.LittleEndian.PutUint32(ill, 0xf90003ff) // MOVD ZR, (ZR)
case "ppc64":
binary.BigEndian.PutUint32(ill, 0x7fe00008) // trap
binary.BigEndian.PutUint32(ill, 0xf8000000) // MOVD R0, (R0)
case "ppc64le":
binary.LittleEndian.PutUint32(ill, 0x7fe00008) // trap
binary.LittleEndian.PutUint32(ill, 0xf8000000) // MOVD R0, (R0)
case "mips", "mips64":
binary.BigEndian.PutUint32(ill, 0x00000034) // trap
binary.BigEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
case "mipsle", "mips64le":
binary.LittleEndian.PutUint32(ill, 0x00000034) // trap
binary.LittleEndian.PutUint32(ill, 0xfc000000) // MOVV R0, (R0)
case "s390x":
binary.BigEndian.PutUint32(ill, 0) // undefined instruction
ill = append(ill, 0xa7, 0x09, 0x00, 0x00) // MOVD $0, R0
ill = append(ill, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x24) // MOVD R0, (R0)
case "riscv64":
binary.LittleEndian.PutUint32(ill, 0x00003023) // MOV X0, (X0)
default:
// Just leave it as 0 and hope for the best.
}