Go version
go version go1.22.3 linux/amd64
Output of go env
in your module/workspace:
GO111MODULE=''
GOARCH='amd64'
GOBIN=''
GOCACHE='/root/.cache/go-build'
GOENV='/root/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMODCACHE='/root/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/root/go'
GOPRIVATE=''
GOPROXY='https://goproxy.io,direct'
GOROOT='/data/build/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/data/build/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.22.3'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='gcc'
CXX='g++'
CGO_ENABLED='1'
GOMOD='/data/tracy/go_server/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 -fdebug-prefix-map=/tmp/go-build2645800351=/tmp/go-build -gno-record-gcc-switches'
What did you do?
package main
import ( "os" "os/signal" "syscall" )
func main() {
pid, _, err := syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
if err != 0 {
return
}
if pid > 0 {
syscall.Exit(0)
}
syscall.Setsid()
pid, _, err = syscall.RawSyscall(syscall.SYS_FORK, 0, 0, 0)
if err != 0 {
return
}
if pid > 0 {
syscall.Exit(0)
}
if err := syscall.Chdir("/"); err != nil {
return
}
fd, err2 := os.OpenFile("/dev/null", os.O_RDWR, 0)
if err2 != nil {
return
}
defer fd.Close()
syscall.Umask(0)
println("111111111111111111111")
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGSEGV) //problem occur
println("222222222222222222222")
for sig := range sigChan {
switch sig {
case syscall.SIGSEGV:
println("333333333333333333")
}
break
}
select {}
}
What did you see happen?
[root@192.168.0.250 access]# ps -ef | grep access root 13804 1 0 13:37 ? 00:00:00 ./access root 13826 9359 0 13:37 pts/1 00:00:00 grep --color=auto access [root@192.168.0.250 access]# dlv attach 13804 Type 'help' for list of commands. (dlv) bt 0 0x00000000004636c3 in runtime.futex at /data/build/go/src/runtime/sys_linux_amd64.s:558 1 0x000000000042e8b0 in runtime.futexsleep at /data/build/go/src/runtime/os_linux.go:69 2 0x000000000040a607 in runtime.notesleep at /data/build/go/src/runtime/lock_futex.go:170 3 0x00000000004397f3 in runtime.mPark at /data/build/go/src/runtime/proc.go:1761 4 0x00000000004397f3 in runtime.stoplockedm at /data/build/go/src/runtime/proc.go:3026 5 0x000000000043bb1a in runtime.schedule at /data/build/go/src/runtime/proc.go:3847 6 0x000000000043c16c in runtime.park_m at /data/build/go/src/runtime/proc.go:4036 7 0x000000000045fa4e in runtime.mcall at /data/build/go/src/runtime/asm_amd64.s:458 (dlv)
What did you expect to see?
The process is executing normally Deadlock occurs not print "222222222222222222222"
create a daemon and custom sign handle
Comment From: ianlancetaylor
Unfortunately you simply can't call fork
in a Go program. In general you can't safely call fork
in any multi-threaded program, and all Go programs are multi-threaded. You'll need to exec the program setting SysProcAttr.Setsid
.