Skip to content

golang.org/x/crypto/ssh: goroutine leak #47541

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
mei-rune opened this issue Aug 4, 2021 · 1 comment
Closed

golang.org/x/crypto/ssh: goroutine leak #47541

mei-rune opened this issue Aug 4, 2021 · 1 comment

Comments

@mei-rune
Copy link

mei-rune commented Aug 4, 2021

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

$ go version
go version go1.16.3 windows/amd64

Does this issue reproduce with the latest release?

yes

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

go env Output
$ go env

What did you do?

d:\developing\go\meijing\src\cn\com\hengwei_private>go env
set GO111MODULE=
set GOARCH=amd64
set GOBIN=
set GOCACHE=d:\developing\go-build
set GOENV=C:\Users\runne\AppData\Roaming\go\env
set GOEXE=.exe
set GOFLAGS=
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOINSECURE=
set GOMODCACHE=d:\developing\go\meijing\pkg\mod
set GONOPROXY=
set GONOSUMDB=
set GOOS=windows
set GOPATH=d:\developing\go\meijing;d:\developing\go\meijing\tpt_vendor;d:\developing\go\meijing..\aah;
set GOPRIVATE=
set GOPROXY=https://goproxy.cn,https://goproxy.io,direct
set GOROOT=d:\tools\go
set GOSUMDB=sum.golang.org
set GOTMPDIR=
set GOTOOLDIR=d:\tools\go\pkg\tool\windows_amd64
set GOVCS=
set GOVERSION=go1.16.3
set GCCGO=gccgo
set AR=ar
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set GOMOD=d:\developing\go\meijing\src\cn\com\hengwei_private\go.mod
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\runne\AppData\Local\Temp\go-build40258698=/tmp/go-build -gno-record-gcc-switches

What did you expect to see?

goroutine profile: total 2892
450 @ 0x43ecfa 0x406c7a 0x4068eb 0xb4b794 0x474b01
#	0xb4b793	golang.org/x/crypto/ssh.(*Client).handleGlobalRequests+0x73	d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/client.go:138

450 @ 0x43ecfa 0x406c7a 0x4068eb 0xb4b819 0x474b01
#	0xb4b818	golang.org/x/crypto/ssh.(*Client).handleChannelOpens+0x58	d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/client.go:147

450 @ 0x43ecfa 0x406c7a 0x4068eb 0xb513f5 0xb6975e 0xb695bc 0x474b01
#	0xb513f4	golang.org/x/crypto/ssh.(*handshakeTransport).readPacket+0x54	d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/handshake.go:187
#	0xb6975d	golang.org/x/crypto/ssh.(*mux).onePacket+0x3d			d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/mux.go:215
#	0xb695bb	golang.org/x/crypto/ssh.(*mux).loop+0x3b			d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/mux.go:190

450 @ 0x43ecfa 0x44fd48 0xb51945 0x474b01
#	0xb51944	golang.org/x/crypto/ssh.(*handshakeTransport).kexLoop+0xe4	d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/handshake.go:268

450 @ 0x43ecfa 0x46f997 0x46f96d 0x47f05f 0xb68b8b 0xb735da 0x474b01
#	0x46f96c	sync.runtime_notifyListWait+0xec		d:/tools/go_amd64/src/runtime/sema.go:513
#	0x47f05e	sync.(*Cond).Wait+0x9e				d:/tools/go_amd64/src/sync/cond.go:56
#	0xb68b8a	golang.org/x/crypto/ssh.(*mux).Wait+0x8a	d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/mux.go:110
#	0xb735d9	golang.org/x/crypto/ssh.NewClient.func1+0x39	d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/client.go:62

448 @ 0x43ecfa 0x434b25 0x46dde5 0x502dac 0x504333 0x505556 0x565fb6 0x579818 0x68ccb8 0x48326e 0xb467a7 0xb46757 0xb7148f 0xb713a5 0xb51f97 0xb514d4 0x474b01
#	0x46dde4	internal/poll.runtime_pollWait+0x64					d:/tools/go_amd64/src/runtime/netpoll.go:222
#	0x502dab	internal/poll.(*pollDesc).wait+0x4b					d:/tools/go_amd64/src/internal/poll/fd_poll_runtime.go:87
#	0x504332	internal/poll.execIO+0x112						d:/tools/go_amd64/src/internal/poll/fd_windows.go:175
#	0x505555	internal/poll.(*FD).Read+0x2f5						d:/tools/go_amd64/src/internal/poll/fd_windows.go:441
#	0x565fb5	net.(*netFD).Read+0x55							d:/tools/go_amd64/src/net/fd_posix.go:55
#	0x579817	net.(*conn).Read+0x97							d:/tools/go_amd64/src/net/net.go:183
#	0x68ccb7	bufio.(*Reader).Read+0x237						d:/tools/go_amd64/src/bufio/bufio.go:227
#	0x48326d	io.ReadAtLeast+0x8d							d:/tools/go_amd64/src/io/io.go:328
#	0xb467a6	io.ReadFull+0x86							d:/tools/go_amd64/src/io/io.go:347
#	0xb46756	golang.org/x/crypto/ssh.(*streamPacketCipher).readCipherPacket+0x36	d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/cipher.go:153
#	0xb7148e	golang.org/x/crypto/ssh.(*connectionState).readPacket+0x6e		d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/transport.go:130
#	0xb713a4	golang.org/x/crypto/ssh.(*transport).readPacket+0x44			d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/transport.go:114
#	0xb51f96	golang.org/x/crypto/ssh.(*handshakeTransport).readOnePacket+0x56	d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/handshake.go:374
#	0xb514d3	golang.org/x/crypto/ssh.(*handshakeTransport).readLoop+0x53		d:/developing/go/meijing/tpt_vendor/src/golang.org/x/crypto/ssh/handshake.go:197

What did you see instead?

goroutine no leak

My code is

	conn, err := ssh.Dial("tcp", client.host, config)
	if err != nil {
		return errors.New("connect failed, " + err.Error())
        }
	defer conn.Close()
	
	for {
                .........
               bs, err := executeRequest(conn, request)
                if nil != err {
		      return errors.New("execute failed, " + err.Error())
               }
               ...
        }


...
func executeRequest()  ([]byte, error) {
	sess, e := conn.NewSession()
	if nil != e {
		return nil, e
	}
	defer sess.Close()

	var b safeWriter
	sess.Stdout = &b
	sess.Stderr = &b
	e = sess.Start(cmd)
	if e != nil {
		return nil, e
	}

	c := make(chan error, 1)
	go func() {
		c <- sess.Wait()
	}()

	timer := time.NewTimer(command_timeout)
	select {
	case e = <-c:
		timer.Stop()
		return b.b.Bytes(), e
	case <-timer.C:
		e = sess.Signal(ssh.SIGINT)
		if e != nil {
			timer.Reset(10 * time.Second)
			select {
			case e = <-c:
				timer.Stop()
			case <-timer.C:
				sess.Signal(ssh.SIGKILL)
			}
			log.Println("execute '" + cmd + "' is timeout")
			e = errors.NewRuntimeError(sampling.TimeoutError.ErrorCode(), "execute '"+cmd+"' is timeout")
		}
		return b.b.Bytes(), e
	}
       ........
}
@mei-rune mei-rune closed this as completed Aug 5, 2021
@YenchangChan
Copy link

I have the same problem as you, how do you solve it?

@golang golang locked and limited conversation to collaborators Jun 14, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants