blob: 4a775be623b709d963b6df7d4c8f030acca136d3 [file] [log] [blame]
// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package testenv
import (
"os"
"runtime"
)
// RunThenCrash sets the provided core dump filter (optional) for
// the process, runs f, then crashes.
//
// The slice returned by f is kept alive across the crash.
func RunThenCrash(coredumpFilter string, f func() any) {
// Set coredump filter (Linux only).
if runtime.GOOS == "linux" && coredumpFilter != "" {
if err := os.WriteFile("/proc/self/coredump_filter", []byte(coredumpFilter), 0600); err != nil {
os.Stderr.WriteString("crash: unable to set coredump_filter: ")
os.Stderr.WriteString(err.Error())
os.Stderr.WriteString("\n")
os.Exit(0) // Don't crash (which is an error for the called).
}
}
// Run f.
result := f()
crash()
runtime.KeepAlive(result)
}
// Crash crashes the program.
//
// Make it noinline so registers are spilled before entering, otherwise imprecise DWARF will be our doom.
// Delve has trouble with this too; 'result' in RunThenCrash won't be visible otherwise.
//
//go:noinline
func crash() {
_ = *(*int)(nil)
}