Skip to content

Go process receiving SIGABRT or SIGSEGV signals is exiting with 2 exit status #72084

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
3v1n0 opened this issue Mar 3, 2025 · 4 comments
Closed
Labels
BugReport Issues describing a possible bug in the Go implementation.

Comments

@3v1n0
Copy link

3v1n0 commented Mar 3, 2025

Go version

go1.23.6

Output of go env in your module/workspace:

❯ go env
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/home/marco/.cache/go-build'
GOENV='/home/marco/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/home/marco/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/marco/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/marco/go/pkg/mod/golang.org/[email protected]'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/marco/go/pkg/mod/golang.org/[email protected]/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.23.6'
GODEBUG=''
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/marco/.config/go/telemetry'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/DEV/authd/go.mod'
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 -ffile-prefix-map=/tmp/go-build3717024177=/tmp/go-build -gno-record-gcc-switches'

What did you do?

Having a simple go process around and signaling it (or itself) with SIGSEGV or SIGABRT makes the process to show the trace and then exit 2 exit status, instead of with the right signal exit code.

Or similar using:

package main

import (
	"os"
	"syscall"
	"time"
)

func main() {
	go func() {
		syscall.Kill(os.Getpid(), syscall.SIGSEGV)
	}()
	time.Sleep(10 * time.Second)
}

What did you see happen?

While having the trace can be useful, the process should then consistently exit in the same way it has been stopped, by calling the default handler for such signals.

In fact calling a go process from another C process, and doing

int status;
int exit_status = EXIT_FAILURE;
pid_t ret = waitpid (child_pid, &status, 0);

printf ("Waiting pid %d returned %d, "
          "exited: %d, signaled: %d", child_pid, ret,
          WIFEXITED (status), WIFSIGNALED (status));

if (ret == child_pid && WIFEXITED (status))
  {
    printf ("Exit status is %d\n", WEXITSTATUS (status));
    exit_status = WEXITSTATUS (status);
  }

For a go process that gets signaled we receive:

Waiting pid 277520, returned 277520, exited: 1, signaled: 0
Exit status is 2

And this is wrong because it makes impossible for the calling process to figure out what's the reason for the process being stopped (and react accordingly).

What did you expect to see?

The calling process should instead print Waiting pid 277520, returned 277520, exited: 0, signaled: 1 and WTERMSIG should provide the signal information.

This works well in fact when using SIGKILL or other signals that aren't handled by go by default.

@gabyhelp gabyhelp added the BugReport Issues describing a possible bug in the Go implementation. label Mar 3, 2025
@seankhliao
Copy link
Member

This is a documented behaviour of the runtime package (exit 2 on crash).

@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Mar 3, 2025
@3v1n0
Copy link
Author

3v1n0 commented Mar 3, 2025

Well even though that's documented I feel that's wrong and a bug to be planned.

And at least an env variable should be provided to define the exit code, given that 2 can be used by the program for other purposes.

3v1n0 added a commit to 3v1n0/authd that referenced this issue Mar 3, 2025
Sadly some signals such as SIGABRT or SIGSEGV are handled by go and in
the wrong way because it never redirects them as expected, so in such
cases we just fail with a normal exit error instead of because of a
signal.

Reported this upstream and adding comments about.

See: golang/go#72084
3v1n0 added a commit to 3v1n0/authd that referenced this issue Mar 3, 2025
Sadly some signals such as SIGABRT or SIGSEGV are handled by go and in
the wrong way because it never redirects them as expected, so in such
cases we just fail with a normal exit error instead of because of a
signal.

Reported this upstream and adding comments about.

See: golang/go#72084
3v1n0 added a commit to 3v1n0/authd that referenced this issue Mar 3, 2025
Sadly some signals such as SIGABRT or SIGSEGV are handled by go and in
the wrong way because it never redirects them as expected, so in such
cases we just fail with a normal exit error instead of because of a
signal.

Reported this upstream and adding comments about.

See: golang/go#72084
3v1n0 added a commit to 3v1n0/authd that referenced this issue Mar 3, 2025
Sadly some signals such as SIGABRT or SIGSEGV are handled by go and in
the wrong way because it never redirects them as expected, so in such
cases we just fail with a normal exit error instead of because of a
signal.

Reported this upstream and adding comments about.

See: golang/go#72084
3v1n0 added a commit to 3v1n0/authd that referenced this issue Mar 3, 2025
Sadly some signals such as SIGABRT or SIGSEGV are handled by go and in
the wrong way because it never redirects them as expected, so in such
cases we just fail with a normal exit error instead of because of a
signal.

Reported this upstream and adding comments about.

See: golang/go#72084
@ianlancetaylor
Copy link
Contributor

Unfortunately I don't think we can change this behavior now.

3v1n0 added a commit to 3v1n0/authd that referenced this issue Mar 12, 2025
Sadly some signals such as SIGABRT or SIGSEGV are handled by go and in
the wrong way because it never redirects them as expected, so in such
cases we just fail with a normal exit error instead of because of a
signal.

Reported this upstream and adding comments about.

See: golang/go#72084
3v1n0 added a commit to 3v1n0/authd that referenced this issue Mar 12, 2025
Sadly some signals such as SIGABRT or SIGSEGV are handled by go and in
the wrong way because it never redirects them as expected, so in such
cases we just fail with a normal exit error instead of because of a
signal.

Reported this upstream and adding comments about.

See: golang/go#72084
3v1n0 added a commit to 3v1n0/authd that referenced this issue Mar 12, 2025
Sadly some signals such as SIGABRT or SIGSEGV are handled by go and in
the wrong way because it never redirects them as expected, so in such
cases we just fail with a normal exit error instead of because of a
signal.

Reported this upstream and adding comments about.

See: golang/go#72084
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
BugReport Issues describing a possible bug in the Go implementation.
Projects
None yet
Development

No branches or pull requests

4 participants