Repository: go
Issue: runtime: fatal error stack traces are swallowed for binaries with elevated privileges
Labels: NeedsInvestigation,compiler/runtime

### Go version

go version go1.22.4 linux/amd64

### Output of `go env` in your module/workspace:

```shell
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/ronanj/.cache/go-build'
GOENV='/home/ronanj/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/ronanj/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/ronanj/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.4'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build4169732472=/tmp/go-build -gno-record-gcc-switches'
```


### What did you do?

The following program will generate a `fatal error: concurrent map writes`

```go
package main

import (
	"runtime/debug"
	"time"
)

var l = map[nt]int{}

func worker() {
	for {
		l[1] = 0
	}
}

func main() {
	debug.SetTraceback("all")
	go worker()
	go worker()
	for {
		time.Sleep(time.Second)
	}
}
```

Run it with go run

```bash
$go build -o test test.go
$./test
fatal error: concurrent map writes

goroutine 6 gp=0xc000007500 m=2 mp=0xc000048808 [running]:
runtime.fatal({0x47c06b?, 0x0?})
	/usr/local/go/src/runtime/panic.go:1042 +0x5c fp=0xc000044f78 sp=0xc000044f48 pc=0x430fdc
runtime.mapassign_fast64(0x46e140, 0xc000072090, 0x1)
	/usr/local/go/src/runtime/map_fast64.go:102 +0x4d fp=0xc000044fb8 sp=0xc000044f78 pc=0x40ed2d
main.worker()
	/tmp/test.go:12 +0x26 fp=0xc000044fe0 sp=0xc000044fb8 pc=0x4654e6
runtime.goexit({})
	/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc000044fe8 sp=0xc000044fe0 pc=0x45f101
created by main.main in goroutine 1
	/tmp/test.go:18 +0x2b

goroutine 1 gp=0xc0000061c0 m=nil [sleep]:
runtime.gopark(0x1bdc37393cd958?, 0xc000042700?, 0x40?, 0xd4?, 0x480f28?)
	/usr/local/go/src/runtime/proc.go:402 +0xce fp=0xc0000426f0 sp=0xc0000426d0 pc=0x433dee
time.Sleep(0x3b9aca00)
	/usr/local/go/src/runtime/time.go:195 +0x115 fp=0xc000042730 sp=0xc0000426f0 pc=0x45c395
main.main()
	/tmp/test.go:21 +0x45 fp=0xc000042750 sp=0xc000042730 pc=0x465545
runtime.main()
	/usr/local/go/src/runtime/proc.go:271 +0x29d fp=0xc0000427e0 sp=0xc000042750 pc=0x4339bd
runtime.goexit({})
	/usr/local/go/src/runtime/asm_amd64.s:1695 +0x1 fp=0xc0000427e8 sp=0xc0000427e0 pc=0x45f101```

...
```

Now run it with elevated privileges

```
$ go build -o test test.go
$ sudo setcap CAP_NET_BIND_SERVICE+eip ./test
$ ./test
fatal error: concurrent map writes
```

Stack traces are gone.

### What did you see happen?

A stack trace

### What did you expect to see?

Referring to https://github.com/golang/go/issues/60272, I expected the traces to be shown when using `debug.SetTraceback("all")`. But this solution only works for `panic` errors, and does not for `fatal` errors thrown internally from the go runtime (especially the map implementation).

Referring to the internal go runtime [panic.go](https://cs.opensource.google/go/go/+/master:src/runtime/panic.go;drc=2a7ca156b8189c68c0a29b4c66194a42c5ce3c9b;l=1076), it is mentioned that *fatal does not include runtime frames, system goroutines, or frame metadata (fp, sp, pc) in the stack trace unless GOTRACEBACK=system or higher*. Setting `SetTraceback` to `system` does not work either, as traces are also swallowed.

This issue, related to the change https://github.com/golang/go/issues/60272 , is because the `fatal` function only checks for [`isSecureMode`](https://cs.opensource.google/go/go/+/master:src/runtime/panic.go;drc=4f77a83589baa5a3038cc6e35615084dc7e5f0c1;l=1239), while the `panic` function checks the [`gotraceback`](https://cs.opensource.google/go/go/+/master:src/runtime/panic.go;drc=4f77a83589baa5a3038cc6e35615084dc7e5f0c1;l=1376) value before dumping the stack trace.