From 1f2e58d89b754c28ba7448ead7d8d9ae8957ab49 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 2 Nov 2020 12:01:33 +0100 Subject: [release-branch.go1.15] internal/poll: treat copy_file_range EIO as not-handled For #42334 Fixes #42369 Change-Id: Ife51df4e7d2539a04393abfdec45e3f902975fca Reviewed-on: https://go-review.googlesource.com/c/go/+/266940 Trust: Tobias Klauser Run-TryBot: Tobias Klauser TryBot-Result: Go Bot Reviewed-by: Ian Lance Taylor (cherry picked from commit 633f9e206045176a12c301eb2c249c1c1d9a5d2e) Reviewed-on: https://go-review.googlesource.com/c/go/+/267917 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Reviewed-by: Tobias Klauser --- src/internal/poll/copy_file_range_linux.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/internal/poll/copy_file_range_linux.go b/src/internal/poll/copy_file_range_linux.go index 09de299ff7..24bee614a6 100644 --- a/src/internal/poll/copy_file_range_linux.go +++ b/src/internal/poll/copy_file_range_linux.go @@ -41,7 +41,7 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err // use copy_file_range(2) again. atomic.StoreInt32(©FileRangeSupported, 0) return 0, false, nil - case syscall.EXDEV, syscall.EINVAL, syscall.EOPNOTSUPP, syscall.EPERM: + case syscall.EXDEV, syscall.EINVAL, syscall.EIO, syscall.EOPNOTSUPP, syscall.EPERM: // Prior to Linux 5.3, it was not possible to // copy_file_range across file systems. Similarly to // the ENOSYS case above, if we see EXDEV, we have @@ -53,6 +53,9 @@ func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err // file. This is another case where no data has been // transfered, so we consider it unhandled. // + // If src and dst are on CIFS, we can see EIO. + // See issue #42334. + // // If the file is on NFS, we can see EOPNOTSUPP. // See issue #40731. // -- cgit v1.2.3-54-g00ecf From 730d5f42f919f948ff2841581ecec6fe4b465aee Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 13 Nov 2020 11:05:37 -0800 Subject: [release-branch.go1.15] cmd/go: permit CGO_LDFLAGS to appear in //go:ldflag For #42565 Fixes #42567 Change-Id: If7cf39905d124dbd54dfac6a53ee38270498efed Reviewed-on: https://go-review.googlesource.com/c/go/+/269818 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Jay Conrod (cherry picked from commit 782cf560db4c919790fdb476d1bbe18e5ddf5ffd) Reviewed-on: https://go-review.googlesource.com/c/go/+/270137 --- src/cmd/go/internal/work/exec.go | 15 ++++++++++++ src/cmd/go/testdata/script/ldflag.txt | 44 +++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/cmd/go/testdata/script/ldflag.txt diff --git a/src/cmd/go/internal/work/exec.go b/src/cmd/go/internal/work/exec.go index 13d4c8cbb4..dc0c4fc344 100644 --- a/src/cmd/go/internal/work/exec.go +++ b/src/cmd/go/internal/work/exec.go @@ -2766,6 +2766,21 @@ func (b *Builder) cgo(a *Action, cgoExe, objdir string, pcCFLAGS, pcLDFLAGS, cgo idx = bytes.Index(src, []byte(cgoLdflag)) } } + + // We expect to find the contents of cgoLDFLAGS in flags. + if len(cgoLDFLAGS) > 0 { + outer: + for i := range flags { + for j, f := range cgoLDFLAGS { + if f != flags[i+j] { + continue outer + } + } + flags = append(flags[:i], flags[i+len(cgoLDFLAGS):]...) + break + } + } + if err := checkLinkerFlags("LDFLAGS", "go:cgo_ldflag", flags); err != nil { return nil, nil, err } diff --git a/src/cmd/go/testdata/script/ldflag.txt b/src/cmd/go/testdata/script/ldflag.txt new file mode 100644 index 0000000000..6ceb33bb70 --- /dev/null +++ b/src/cmd/go/testdata/script/ldflag.txt @@ -0,0 +1,44 @@ +# Issue #42565 + +[!cgo] skip + +# We can't build package bad, which uses #cgo LDFLAGS. +cd bad +! go build +stderr no-such-warning + +# We can build package ok with the same flags in CGO_LDFLAGS. +env CGO_LDFLAGS=-Wno-such-warning -Wno-unknown-warning-option +cd ../ok +go build + +# Build a main program that actually uses LDFLAGS. +cd .. +go build -ldflags=-v + +# Because we passed -v the Go linker should print the external linker +# command which should include the flag we passed in CGO_LDFLAGS. +stderr no-such-warning + +-- go.mod -- +module ldflag + +-- bad/bad.go -- +package bad + +// #cgo LDFLAGS: -Wno-such-warning -Wno-unknown-warning +import "C" + +func F() {} +-- ok/ok.go -- +package ok + +import "C" + +func F() {} +-- main.go -- +package main + +import _ "ldflag/ok" + +func main() {} -- cgit v1.2.3-54-g00ecf From efd204ccf78e16ee6792079ba70456ed425cb9c3 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Tue, 27 Oct 2020 16:09:40 -0700 Subject: [release-branch.go1.15] runtime: block signals in needm before allocating M Otherwise, if a signal occurs just after we allocated the M, we can deadlock if the signal handler needs to allocate an M itself. For #42207 Fixes #42636 Change-Id: I76f44547f419e8b1c14cbf49bf602c6e645d8c14 Reviewed-on: https://go-review.googlesource.com/c/go/+/265759 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor TryBot-Result: Go Bot Reviewed-by: Bryan C. Mills (cherry picked from commit 368c40116434532dc0b53b72fa04788ca6742898) Reviewed-on: https://go-review.googlesource.com/c/go/+/271847 --- src/runtime/crash_cgo_test.go | 13 ++++ src/runtime/os_js.go | 2 +- src/runtime/os_plan9.go | 2 +- src/runtime/os_windows.go | 2 +- src/runtime/proc.go | 26 ++++--- src/runtime/signal_unix.go | 8 +- src/runtime/testdata/testprogcgo/needmdeadlock.go | 95 +++++++++++++++++++++++ 7 files changed, 131 insertions(+), 17 deletions(-) create mode 100644 src/runtime/testdata/testprogcgo/needmdeadlock.go diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go index 4872189f16..57c3639f71 100644 --- a/src/runtime/crash_cgo_test.go +++ b/src/runtime/crash_cgo_test.go @@ -600,3 +600,16 @@ func TestEINTR(t *testing.T) { t.Fatalf("want %s, got %s\n", want, output) } } + +// Issue #42207. +func TestNeedmDeadlock(t *testing.T) { + switch runtime.GOOS { + case "plan9", "windows": + t.Skipf("no signals on %s", runtime.GOOS) + } + output := runTestProg(t, "testprogcgo", "NeedmDeadlock") + want := "OK\n" + if output != want { + t.Fatalf("want %s, got %s\n", want, output) + } +} diff --git a/src/runtime/os_js.go b/src/runtime/os_js.go index ff0ee3aa6b..94983b358d 100644 --- a/src/runtime/os_js.go +++ b/src/runtime/os_js.go @@ -59,7 +59,7 @@ func mpreinit(mp *m) { } //go:nosplit -func msigsave(mp *m) { +func sigsave(p *sigset) { } //go:nosplit diff --git a/src/runtime/os_plan9.go b/src/runtime/os_plan9.go index 9e187d2220..8f5380d3d9 100644 --- a/src/runtime/os_plan9.go +++ b/src/runtime/os_plan9.go @@ -167,7 +167,7 @@ func mpreinit(mp *m) { mp.errstr = (*byte)(mallocgc(_ERRMAX, nil, true)) } -func msigsave(mp *m) { +func sigsave(p *sigset) { } func msigrestore(sigmask sigset) { diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go index 769197db46..81d9ccf8f0 100644 --- a/src/runtime/os_windows.go +++ b/src/runtime/os_windows.go @@ -830,7 +830,7 @@ func mpreinit(mp *m) { } //go:nosplit -func msigsave(mp *m) { +func sigsave(p *sigset) { } //go:nosplit diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 2f1272d310..7fa19d867b 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -569,7 +569,7 @@ func schedinit() { typelinksinit() // uses maps, activeModules itabsinit() // uses activeModules - msigsave(_g_.m) + sigsave(&_g_.m.sigmask) initSigmask = _g_.m.sigmask goargs() @@ -1536,6 +1536,18 @@ func needm(x byte) { exit(1) } + // Save and block signals before getting an M. + // The signal handler may call needm itself, + // and we must avoid a deadlock. Also, once g is installed, + // any incoming signals will try to execute, + // but we won't have the sigaltstack settings and other data + // set up appropriately until the end of minit, which will + // unblock the signals. This is the same dance as when + // starting a new m to run Go code via newosproc. + var sigmask sigset + sigsave(&sigmask) + sigblock() + // Lock extra list, take head, unlock popped list. // nilokay=false is safe here because of the invariant above, // that the extra list always contains or will soon contain @@ -1553,14 +1565,8 @@ func needm(x byte) { extraMCount-- unlockextra(mp.schedlink.ptr()) - // Save and block signals before installing g. - // Once g is installed, any incoming signals will try to execute, - // but we won't have the sigaltstack settings and other data - // set up appropriately until the end of minit, which will - // unblock the signals. This is the same dance as when - // starting a new m to run Go code via newosproc. - msigsave(mp) - sigblock() + // Store the original signal mask for use by minit. + mp.sigmask = sigmask // Install g (= m->g0) and set the stack bounds // to match the current stack. We don't actually know @@ -3417,7 +3423,7 @@ func beforefork() { // a signal handler before exec if a signal is sent to the process // group. See issue #18600. gp.m.locks++ - msigsave(gp.m) + sigsave(&gp.m.sigmask) sigblock() // This function is called before fork in syscall package. diff --git a/src/runtime/signal_unix.go b/src/runtime/signal_unix.go index 80fd2d6604..003c7b0bc8 100644 --- a/src/runtime/signal_unix.go +++ b/src/runtime/signal_unix.go @@ -1032,15 +1032,15 @@ func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool { return true } -// msigsave saves the current thread's signal mask into mp.sigmask. +// sigsave saves the current thread's signal mask into *p. // This is used to preserve the non-Go signal mask when a non-Go // thread calls a Go function. // This is nosplit and nowritebarrierrec because it is called by needm // which may be called on a non-Go thread with no g available. //go:nosplit //go:nowritebarrierrec -func msigsave(mp *m) { - sigprocmask(_SIG_SETMASK, nil, &mp.sigmask) +func sigsave(p *sigset) { + sigprocmask(_SIG_SETMASK, nil, p) } // msigrestore sets the current thread's signal mask to sigmask. @@ -1112,7 +1112,7 @@ func minitSignalStack() { // thread's signal mask. When this is called all signals have been // blocked for the thread. This starts with m.sigmask, which was set // either from initSigmask for a newly created thread or by calling -// msigsave if this is a non-Go thread calling a Go function. It +// sigsave if this is a non-Go thread calling a Go function. It // removes all essential signals from the mask, thus causing those // signals to not be blocked. Then it sets the thread's signal mask. // After this is called the thread can receive signals. diff --git a/src/runtime/testdata/testprogcgo/needmdeadlock.go b/src/runtime/testdata/testprogcgo/needmdeadlock.go new file mode 100644 index 0000000000..5a9c359006 --- /dev/null +++ b/src/runtime/testdata/testprogcgo/needmdeadlock.go @@ -0,0 +1,95 @@ +// Copyright 2020 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// +build !plan9,!windows + +package main + +// This is for issue #42207. +// During a call to needm we could get a SIGCHLD signal +// which would itself call needm, causing a deadlock. + +/* +#include +#include +#include +#include + +extern void GoNeedM(); + +#define SIGNALERS 10 + +static void* needmSignalThread(void* p) { + pthread_t* pt = (pthread_t*)(p); + int i; + + for (i = 0; i < 100; i++) { + if (pthread_kill(*pt, SIGCHLD) < 0) { + return NULL; + } + usleep(1); + } + return NULL; +} + +// We don't need many calls, as the deadlock is only likely +// to occur the first couple of times that needm is called. +// After that there will likely be an extra M available. +#define CALLS 10 + +static void* needmCallbackThread(void* p) { + int i; + + for (i = 0; i < SIGNALERS; i++) { + sched_yield(); // Help the signal threads get started. + } + for (i = 0; i < CALLS; i++) { + GoNeedM(); + } + return NULL; +} + +static void runNeedmSignalThread() { + int i; + pthread_t caller; + pthread_t s[SIGNALERS]; + + pthread_create(&caller, NULL, needmCallbackThread, NULL); + for (i = 0; i < SIGNALERS; i++) { + pthread_create(&s[i], NULL, needmSignalThread, &caller); + } + for (i = 0; i < SIGNALERS; i++) { + pthread_join(s[i], NULL); + } + pthread_join(caller, NULL); +} +*/ +import "C" + +import ( + "fmt" + "os" + "time" +) + +func init() { + register("NeedmDeadlock", NeedmDeadlock) +} + +//export GoNeedM +func GoNeedM() { +} + +func NeedmDeadlock() { + // The failure symptom is that the program hangs because of a + // deadlock in needm, so set an alarm. + go func() { + time.Sleep(5 * time.Second) + fmt.Println("Hung for 5 seconds") + os.Exit(1) + }() + + C.runNeedmSignalThread() + fmt.Println("OK") +} -- cgit v1.2.3-54-g00ecf From 20f50bba49e6338793a5711dc1c6ed60e4b10df8 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Mon, 9 Nov 2020 11:25:38 +0100 Subject: [release-branch.go1.15] internal/poll: use copy_file_range only on Linux kernel >= 5.3 https://man7.org/linux/man-pages/man2/copy_file_range.2.html#VERSIONS states: A major rework of the kernel implementation occurred in 5.3. Areas of the API that weren't clearly defined were clarified and the API bounds are much more strictly checked than on earlier kernels. Applications should target the behaviour and requirements of 5.3 kernels. Rather than attempting to detect the file system for source and destination files (which means two additional statfs syscalls) and skip copy_file_range in case of known defects (e.g. CIFS -> CIFS), just assume copy_file_range to be broken on kernels < 5.3. Fixes #42550 Change-Id: I3a531296182c1d6e341772cc9d2be5bf83e52575 Reviewed-on: https://go-review.googlesource.com/c/go/+/268338 Trust: Tobias Klauser Run-TryBot: Tobias Klauser TryBot-Result: Go Bot Reviewed-by: Ian Lance Taylor (cherry picked from commit 1c7650aa93bd53b7df0bbb34693fc5a16d9f67af) Reviewed-on: https://go-review.googlesource.com/c/go/+/269759 Trust: Ian Lance Taylor Run-TryBot: Ian Lance Taylor Reviewed-by: Dmitri Shuralyov --- src/internal/poll/copy_file_range_linux.go | 50 ++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/src/internal/poll/copy_file_range_linux.go b/src/internal/poll/copy_file_range_linux.go index 24bee614a6..fc34aef4cb 100644 --- a/src/internal/poll/copy_file_range_linux.go +++ b/src/internal/poll/copy_file_range_linux.go @@ -10,15 +10,61 @@ import ( "syscall" ) -var copyFileRangeSupported int32 = 1 // accessed atomically +var copyFileRangeSupported int32 = -1 // accessed atomically const maxCopyFileRangeRound = 1 << 30 +func kernelVersion() (major int, minor int) { + var uname syscall.Utsname + if err := syscall.Uname(&uname); err != nil { + return + } + + rl := uname.Release + var values [2]int + vi := 0 + value := 0 + for _, c := range rl { + if '0' <= c && c <= '9' { + value = (value * 10) + int(c-'0') + } else { + // Note that we're assuming N.N.N here. If we see anything else we are likely to + // mis-parse it. + values[vi] = value + vi++ + if vi >= len(values) { + break + } + value = 0 + } + } + switch vi { + case 0: + return 0, 0 + case 1: + return values[0], 0 + case 2: + return values[0], values[1] + } + return +} + // CopyFileRange copies at most remain bytes of data from src to dst, using // the copy_file_range system call. dst and src must refer to regular files. func CopyFileRange(dst, src *FD, remain int64) (written int64, handled bool, err error) { - if atomic.LoadInt32(©FileRangeSupported) == 0 { + if supported := atomic.LoadInt32(©FileRangeSupported); supported == 0 { return 0, false, nil + } else if supported == -1 { + major, minor := kernelVersion() + if major > 5 || (major == 5 && minor >= 3) { + atomic.StoreInt32(©FileRangeSupported, 1) + } else { + // copy_file_range(2) is broken in various ways on kernels older than 5.3, + // see issue #42400 and + // https://man7.org/linux/man-pages/man2/copy_file_range.2.html#VERSIONS + atomic.StoreInt32(©FileRangeSupported, 0) + return 0, false, nil + } } for remain > 0 { max := remain -- cgit v1.2.3-54-g00ecf From 16ddb8bc763c33fb172d0c1bcd04d070f36f9cc8 Mon Sep 17 00:00:00 2001 From: Alessandro Arzilli Date: Thu, 12 Nov 2020 14:58:46 +0100 Subject: [release-branch.go1.15] cmd/compile: do not emit an extra debug_line entry for the end of seq addr Uses DW_LNS_advance_pc directly, instead of calling putpclcdelta because the latter will create a new debug_line entry for the end of sequence address. Updates #42484. Fixes #42521. Change-Id: Ib6355605cac101b9bf37a3b4961ab0cee678a839 Reviewed-on: https://go-review.googlesource.com/c/go/+/268937 Trust: Than McIntosh Run-TryBot: Than McIntosh TryBot-Result: Go Bot Reviewed-by: Than McIntosh Reviewed-by: Cherry Zhang Reviewed-on: https://go-review.googlesource.com/c/go/+/269517 --- src/cmd/internal/obj/dwarf.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cmd/internal/obj/dwarf.go b/src/cmd/internal/obj/dwarf.go index cd1d5b8687..8a12849d77 100644 --- a/src/cmd/internal/obj/dwarf.go +++ b/src/cmd/internal/obj/dwarf.go @@ -106,7 +106,8 @@ func (ctxt *Link) generateDebugLinesSymbol(s, lines *LSym) { // GDB will assign a line number of zero the last row in the line // table, which we don't want. lastlen := uint64(s.Size - (lastpc - s.Func.Text.Pc)) - putpclcdelta(ctxt, dctxt, lines, lastlen, 0) + dctxt.AddUint8(lines, dwarf.DW_LNS_advance_pc) + dwarf.Uleb128put(dctxt, lines, int64(lastlen)) dctxt.AddUint8(lines, 0) // start extended opcode dwarf.Uleb128put(dctxt, lines, 1) dctxt.AddUint8(lines, dwarf.DW_LNE_end_sequence) -- cgit v1.2.3-54-g00ecf From a2adbc876e9362f064afffcb51ce677e2f988c5e Mon Sep 17 00:00:00 2001 From: Keith Randall Date: Fri, 20 Nov 2020 13:53:05 -0800 Subject: [release-branch.go1.15] cmd/compile: sign extend consant folding properly MOVLconst must have a properly sign-extended auxint constant. The bit operations in these rules don't enforce that invariant. The easiest fix is just to turn on properly typed auxint fields (which is what fixed this issue at tip). Fixes #42753 Change-Id: I264245fad45067a6ade65326f7fe681feb5f3739 Reviewed-on: https://go-review.googlesource.com/c/go/+/272028 Trust: Keith Randall Run-TryBot: Keith Randall TryBot-Result: Go Bot Reviewed-by: David Chase --- src/cmd/compile/internal/ssa/gen/AMD64.rules | 6 +++--- src/cmd/compile/internal/ssa/rewriteAMD64.go | 18 +++++++++--------- test/fixedbugs/issue42753.go | 13 +++++++++++++ 3 files changed, 25 insertions(+), 12 deletions(-) create mode 100644 test/fixedbugs/issue42753.go diff --git a/src/cmd/compile/internal/ssa/gen/AMD64.rules b/src/cmd/compile/internal/ssa/gen/AMD64.rules index ee9ccfb41c..f7eb92dc8b 100644 --- a/src/cmd/compile/internal/ssa/gen/AMD64.rules +++ b/src/cmd/compile/internal/ssa/gen/AMD64.rules @@ -1429,11 +1429,11 @@ (NOTQ (MOVQconst [c])) -> (MOVQconst [^c]) (NOTL (MOVLconst [c])) -> (MOVLconst [^c]) (BTSQconst [c] (MOVQconst [d])) -> (MOVQconst [d|(1< (MOVLconst [d|(1< (MOVLconst [d|(1< (MOVQconst [d&^(1< (MOVLconst [d&^(1< (MOVLconst [d&^(1< (MOVQconst [d^(1< (MOVLconst [d^(1< (MOVLconst [d^(1< Date: Tue, 17 Nov 2020 19:10:51 -0500 Subject: [release-branch.go1.15] cmd/link: recompute heapPos after copyHeap Immediately after a forward Seek, the offset we're writing to is beyond len(buf)+len(heap): |<--- buf --->|<--- heap --->| ^ off If we do a copyHeap at this point, the new heapPos should not be 0: |<---------- buf ----------->|<-heap->| ^ off Recompute it. Updates #42082 Fixes #42948 Change-Id: Icb3e4e1c7bf7d1fd3d76a2e0d7dfcb319c661534 Reviewed-on: https://go-review.googlesource.com/c/go/+/270942 Run-TryBot: Carlos Amedee TryBot-Result: Go Bot Reviewed-by: Than McIntosh Reviewed-by: Jeremy Faller Trust: Cherry Zhang --- src/cmd/link/internal/ld/outbuf.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/cmd/link/internal/ld/outbuf.go b/src/cmd/link/internal/ld/outbuf.go index 09162ae90f..7bc89540c6 100644 --- a/src/cmd/link/internal/ld/outbuf.go +++ b/src/cmd/link/internal/ld/outbuf.go @@ -187,7 +187,9 @@ func (out *OutBuf) writeLoc(lenToWrite int64) (int64, []byte) { // See if our heap would grow to be too large, and if so, copy it to the end // of the mmapped area. if heapLen > maxOutBufHeapLen && out.copyHeap() { - heapPos, heapLen, lenNeeded = 0, 0, lenToWrite + heapPos -= heapLen + lenNeeded = heapPos + lenToWrite + heapLen = 0 } out.heap = append(out.heap, make([]byte, lenNeeded-heapLen)...) } -- cgit v1.2.3-54-g00ecf From 9b955d2d3fcff6a5bc8bce7bafdc4c634a28e95b Mon Sep 17 00:00:00 2001 From: Carlos Amedee Date: Thu, 3 Dec 2020 11:05:59 -0500 Subject: [release-branch.go1.15] go1.15.6 Change-Id: I9e050e1463f1bc01c04d1817aef2f81a5aac4d42 Reviewed-on: https://go-review.googlesource.com/c/go/+/275132 Run-TryBot: Carlos Amedee TryBot-Result: Go Bot Reviewed-by: Dmitri Shuralyov Trust: Carlos Amedee --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index d4bbebb9fc..ea3b51f95d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -go1.15.5 \ No newline at end of file +go1.15.6 \ No newline at end of file -- cgit v1.2.3-54-g00ecf