Skip to content

runtime: infinite loop in lockextra on linux/arm #34391

Closed
@nyuichi

Description

@nyuichi

What version of Go are you using (go version)?

$ go/bin/go version
go version devel +dac30212c2 Tue Sep 10 07:31:41 2019 +0100 linux/arm

Does this issue reproduce with the latest release?

I only reproduced this with HEAD due to another issue #34030.

What operating system and processor architecture are you using (go env)?

go env Output
$ go/bin/go env
GO111MODULE=""
GOARCH="arm"
GOBIN=""
GOCACHE="/home/pi/.cache/go-build"
GOENV="/home/pi/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="arm"
GOHOSTOS="linux"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH=""
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/home/pi/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/home/pi/go/pkg/tool/linux_arm"
GCCGO="gccgo"
GOARM="7"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -marm -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build423836175=/tmp/go-build -gno-record-gcc-switches"

What did you do?

My environment is Raspberry pi 3 running raspbian buster.

$ cat bug.go 
package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	signal_chan := make(chan os.Signal, 1)
	signal.Notify(signal_chan, syscall.SIGUSR1)
	go func() {
		for {
			<-signal_chan
		}
	}()

	p, _ := os.FindProcess(os.Getpid())

	go func() {
		for {
			p.Signal(syscall.SIGUSR1)
		}
	}()

        t0 := time.Now()
        t1 := t0
        for t1.Sub(t0) < 60 * time.Second {
                t1 = time.Now()
		fmt.Println("{}", t1)
        }
	fmt.Println("done")
}
$ go/bin/go build bug.go
$ gdb bug
Reading symbols from bug...done.
Loading Go Runtime support.
(gdb) handle SIGUSR1 nostop noprint
Signal        Stop	Print	Pass to program	Description
SIGUSR1       No	No	Yes		User defined signal 1
(gdb) r
Starting program: /home/pi/bug 
[New LWP 3815]
[New LWP 3816]
[New LWP 3817]
[New LWP 3818]
[New LWP 3819]
[New LWP 3820]
[New LWP 3821]
{} 2019-09-19 08:21:27.266727698 +0100 BST m=+0.002104470
{} 2019-09-19 08:21:27.268343107 +0100 BST m=+0.003719983
{} 2019-09-19 08:21:27.268407117 +0100 BST m=+0.003783941
... (omit) ...
{} 2019-09-19 08:22:04.869803408 +0100 BST m=+37.605180023
{} 2019-09-19 08:22:04.869853199 +0100 BST m=+37.605229814
{} 2019-09-19 08:22:04.869910438 +0100 BST m=+37.605287106
### (at this point the log suddenly stops coming) ###
^C
### (interrupt with Ctrl-C after waiting a while) ###
Thread 1 "bug" received signal SIGINT, Interrupt.
runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
334		SWI	$0
(gdb) info threads
  Id   Target Id         Frame 
* 1    LWP 3812 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
  2    LWP 3815 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
  3    LWP 3816 "bug"    runtime.usleep () at /home/pi/go/src/runtime/sys_linux_arm.s:486
  4    LWP 3817 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
  5    LWP 3818 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:335
  6    LWP 3819 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
  7    LWP 3820 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
  8    LWP 3821 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
  9    LWP 3822 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
  10   LWP 3824 "bug"    runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
(gdb) bt
#0  runtime.futex () at /home/pi/go/src/runtime/sys_linux_arm.s:334
#1  0x00037b7c in runtime.futexsleep (addr=0x1602fc <runtime.m0+204>, val=0, ns=-1) at /home/pi/go/src/runtime/os_linux.go:44
#2  0x000191d8 in runtime.notesleep (n=0x1602fc <runtime.m0+204>) at /home/pi/go/src/runtime/lock_futex.go:151
#3  0x00040518 in runtime.stoplockedm () at /home/pi/go/src/runtime/proc.go:2105
#4  0x00041bc4 in runtime.schedule () at /home/pi/go/src/runtime/proc.go:2506
#5  0x00041d34 in runtime.park_m (gp=0x48a1c0) at /home/pi/go/src/runtime/proc.go:2647
#6  0x000633e4 in runtime.mcall () at /home/pi/go/src/runtime/asm_arm.s:289
#7  0x00491574 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) thread 3
[Switching to thread 3 (LWP 3816)]
#0  runtime.usleep () at /home/pi/go/src/runtime/sys_linux_arm.s:486
486		RET
(gdb) bt
#0  runtime.usleep () at /home/pi/go/src/runtime/sys_linux_arm.s:486
#1  0x0003f990 in runtime.lockextra (nilokay=false, ~r1=<optimized out>) at /home/pi/go/src/runtime/proc.go:1794
#2  0x0003f3d4 in runtime.needm (x=<optimized out>) at /home/pi/go/src/runtime/proc.go:1595
#3  0x0004f240 in runtime.badsignal (sig=10, c=0x447c58) at /home/pi/go/src/runtime/signal_unix.go:610
#4  0x0004e9ac in runtime.sigtrampgo (sig=<optimized out>, info=0x447c88, ctx=0x447d08) at /home/pi/go/src/runtime/signal_unix.go:315
#5  0x0006604c in runtime.sigtramp () at /home/pi/go/src/runtime/sys_linux_arm.s:449
#6  0x76ffd3bc in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) 

What did you expect to see?

done is printed.

What did you see instead?

The execution got stuck running into an infinite loop (maybe a livelock).
It appears the issue is caused in the same situation of #34030, namely a signal occurs while VDSO is running.
In the patch I attached in #34030 it is tested that incoming SIGPROF signals no longer cause segv, but I hadn't fully tested other signals.

Metadata

Metadata

Assignees

No one assigned

    Labels

    FrozenDueToAgeNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions