Skip to content
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

cmd/compile: crash in newliveness in Go 1.6 #15235

Closed
mzimmerman opened this issue Apr 11, 2016 · 10 comments
Closed

cmd/compile: crash in newliveness in Go 1.6 #15235

mzimmerman opened this issue Apr 11, 2016 · 10 comments
Milestone

Comments

@mzimmerman
Copy link

Please answer these questions before submitting your issue. Thanks!

  1. What version of Go are you using (go version)?
    go version go1.6 linux/amd64
    go 1.5 also fails but go 1.4 compiles the code successfully
  2. What operating system and processor architecture are you using (go env)?
GOARCH="amd64"
GOBIN=""
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/user"
GORACE=""
GOROOT="/usr/lib/go"
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GO15VENDOREXPERIMENT="1"
CC="gcc"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0"
CXX="g++"
CGO_ENABLED="1"
  1. What did you do?
    I used a shell script to generate some code, specifically a large ~200,000 line slice literal. Code is not public and I have not yet been able to reduce it.
  2. What did you expect to see?
    The code to build successfully.
  3. What did you see instead?
go build file1.go file2.go
# command-line-arguments
panic: runtime error: slice bounds out of range

goroutine 1 [running]:
panic(0x802ba0, 0xc82000e170)
        /usr/lib/go/src/runtime/panic.go:464 +0x3e6
cmd/compile/internal/gc.newliveness(0xc8307042d0, 0xc834448120, 0xc89e58a000, 0x5d235, 0x71800, 0xc89ed48000, 0x10705, 0x12c00, 0x9be070cd77c7929b)
        /usr/lib/go/src/cmd/compile/internal/gc/plive.go:691 +0xc8e
cmd/compile/internal/gc.liveness(0xc8307042d0, 0xc834448120, 0xc84ea6ef80, 0xc84ea6f000)
        /usr/lib/go/src/cmd/compile/internal/gc/plive.go:1782 +0x2cf
cmd/compile/internal/gc.compile(0xc8307042d0)
        /usr/lib/go/src/cmd/compile/internal/gc/pgen.go:541 +0xdf2
cmd/compile/internal/gc.funccompile(0xc8307042d0)
        /usr/lib/go/src/cmd/compile/internal/gc/dcl.go:1450 +0x1c0
cmd/compile/internal/gc.fninit(0xc83353a520)
        /usr/lib/go/src/cmd/compile/internal/gc/init.go:184 +0x8a4
cmd/compile/internal/gc.Main()
        /usr/lib/go/src/cmd/compile/internal/gc/lex.go:477 +0x2150
cmd/compile/internal/amd64.Main()
        /usr/lib/go/src/cmd/compile/internal/amd64/galign.go:127 +0x58d
main.main()
        /usr/lib/go/src/cmd/compile/main.go:32 +0x395
@bradfitz
Copy link
Contributor

Have you tried Go tip?

@bradfitz
Copy link
Contributor

Also, please provide the source code or the source code which generates the source code? If we can't reproduce, it's much less likely we'll fix it.

@bradfitz bradfitz added this to the Unplanned milestone Apr 11, 2016
@bradfitz bradfitz changed the title go build panics - cmd/compile/internal/gc.newliveness cmd/compile: crash in newliveness in Go 1.6 Apr 11, 2016
@mzimmerman
Copy link
Author

I will try to produce a public version.

go tip all.bash fails with a race condition for me, but make.bash was successful. Trying go tip it actually doesn't complete compiling the code and hangs.
go version devel +cabb140 Mon Apr 11 18:34:49 2016 +0000 linux/amd64

[matt@matt-fred ]$ /home/matt/gotip/bin/go build file1.go file2.go
^\SIGQUIT: quit
PC=0x4c9ee1 m=0

goroutine 0 [idle]:
runtime.futex(0xa075d0, 0x0, 0x0, 0x0, 0x0, 0x485c13, 0x0, 0x0, 0x485fe8, 0xa075d0, ...)
        /home/matt/gotip/src/runtime/sys_linux_amd64.s:363 +0x21
runtime.futexsleep(0xa075d0, 0x0, 0xffffffffffffffff)
        /home/matt/gotip/src/runtime/os_linux.go:45 +0x58
runtime.notesleep(0xa075d0)
        /home/matt/gotip/src/runtime/lock_futex.go:145 +0x78
runtime.stopm()
        /home/matt/gotip/src/runtime/proc.go:1564 +0xa3
runtime.findrunnable(0xc82001ea00, 0x0)
        /home/matt/gotip/src/runtime/proc.go:2007 +0x22d
runtime.schedule()
        /home/matt/gotip/src/runtime/proc.go:2106 +0x13c
runtime.park_m(0xc820291c80)
        /home/matt/gotip/src/runtime/proc.go:2169 +0x11a
runtime.mcall(0x7fff1cbeac10)
        /home/matt/gotip/src/runtime/asm_amd64.s:240 +0x5b

goroutine 1 [semacquire]:
sync.runtime_Semacquire(0xc820316fac)
        /home/matt/gotip/src/runtime/sema.go:47 +0x26
sync.(*WaitGroup).Wait(0xc820316fa0)
        /home/matt/gotip/src/sync/waitgroup.go:127 +0x8d
main.(*builder).do(0xc8201a6000, 0xc8201fc000)
        /home/matt/gotip/src/cmd/go/build.go:1312 +0x46c
main.runBuild(0x9ff380, 0xc82008a0e0, 0x2, 0x2)
        /home/matt/gotip/src/cmd/go/build.go:467 +0x67b
main.main()
        /home/matt/gotip/src/cmd/go/main.go:181 +0x642

goroutine 17 [syscall, 1 minutes, locked to thread]:
runtime.goexit()
        /home/matt/gotip/src/runtime/asm_amd64.s:2013 +0x1

goroutine 19 [syscall, 1 minutes]:
os/signal.signal_recv(0x0)
        /home/matt/gotip/src/runtime/sigqueue.go:116 +0x15e
os/signal.loop()
        /home/matt/gotip/src/os/signal/signal_unix.go:22 +0x18
created by os/signal.init.1
        /home/matt/gotip/src/os/signal/signal_unix.go:28 +0x37

goroutine 4 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 5 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 6 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 7 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 8 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 9 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 10 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 11 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 12 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 13 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 14 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 15 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 16 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 50 [syscall]:
syscall.Syscall6(0x3d, 0x4e61, 0xc8201eb224, 0x0, 0xc8203de090, 0x0, 0x0, 0x0, 0xc820196120, 0x47c8a0)
        /home/matt/gotip/src/syscall/asm_linux_amd64.s:44 +0x5
syscall.wait4(0x4e61, 0xc8201eb224, 0x0, 0xc8203de090, 0x90, 0x7ed6e0, 0x1)
        /home/matt/gotip/src/syscall/zsyscall_linux_amd64.go:172 +0x7b
syscall.Wait4(0x4e61, 0xc8201eb26c, 0x0, 0xc8203de090, 0x0, 0x0, 0x13)
        /home/matt/gotip/src/syscall/syscall_linux.go:256 +0x47
os.(*Process).wait(0xc8200fc640, 0xc8203e4700, 0xc820044100, 0xc8203e2000)
        /home/matt/gotip/src/os/exec_unix.go:22 +0xdc
os.(*Process).Wait(0xc8200fc640, 0xc8201eb310, 0x0, 0x0)
        /home/matt/gotip/src/os/doc.go:49 +0x21
os/exec.(*Cmd).Wait(0xc8203e2140, 0x0, 0x0)
        /home/matt/gotip/src/os/exec/exec.go:396 +0x58
os/exec.(*Cmd).Run(0xc8203e2140, 0x0, 0x0)
        /home/matt/gotip/src/os/exec/exec.go:262 +0x3e
main.(*builder).runOut(0xc8201a6000, 0xc82014c370, 0xc, 0x8227c8, 0x16, 0x0, 0x0, 0x0, 0xc8200ce160, 0xe, ...)
        /home/matt/gotip/src/cmd/go/build.go:2033 +0x44d
main.gcToolchain.gc(0xc8201a6000, 0xc8201b6000, 0xc820271a40, 0x2f, 0xc8202d6600, 0x33, 0xc82008dc00, 0xc820220540, 0x4, 0x4, ...)
        /home/matt/gotip/src/cmd/go/build.go:2294 +0x102b
main.(*gcToolchain).gc(0xa22f60, 0xc8201a6000, 0xc8201b6000, 0xc820271a40, 0x2f, 0xc8202d6600, 0x33, 0x0, 0xc820220540, 0x4, ...)
        <autogenerated>:5 +0xff
main.(*builder).build(0xc8201a6000, 0xc82021f520, 0x0, 0x0)
        /home/matt/gotip/src/cmd/go/build.go:1468 +0x119a
main.(*builder).do.func1(0xc82021f520)
        /home/matt/gotip/src/cmd/go/build.go:1246 +0x72
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1303 +0x126
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 51 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 52 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 53 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 54 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 55 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 56 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 57 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 58 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 59 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 60 [select]:
main.(*builder).do.func2(0xc820316fa0, 0xc8201a6000, 0xc820399460)
        /home/matt/gotip/src/cmd/go/build.go:1293 +0x18e
created by main.(*builder).do
        /home/matt/gotip/src/cmd/go/build.go:1309 +0x443

goroutine 82 [syscall]:
syscall.Syscall(0x0, 0x4, 0xc8202ea200, 0x200, 0x0, 0x200, 0x0)
        /home/matt/gotip/src/syscall/asm_linux_amd64.s:18 +0x5
syscall.read(0x4, 0xc8202ea200, 0x200, 0x200, 0x1, 0xc8202ea200, 0x0)
        /home/matt/gotip/src/syscall/zsyscall_linux_amd64.go:783 +0x4b
syscall.Read(0x4, 0xc8202ea200, 0x200, 0x200, 0x0, 0xc820493c00, 0xc820468f00)
        /home/matt/gotip/src/syscall/syscall_unix.go:161 +0x3f
os.(*File).read(0xc8200440a8, 0xc8202ea200, 0x200, 0x200, 0x4ce691, 0x767d60, 0x200)
        /home/matt/gotip/src/os/file_unix.go:228 +0x45
os.(*File).Read(0xc8200440a8, 0xc8202ea200, 0x200, 0x200, 0x0, 0x300000002, 0xc820468f00)
        /home/matt/gotip/src/os/file.go:97 +0x4c
bytes.(*Buffer).ReadFrom(0xc8200bc000, 0x9dfbe0, 0xc8200440a8, 0xc820042ea8, 0x485c01, 0xc82031a178)
        /home/matt/gotip/src/bytes/buffer.go:176 +0x149
io.copyBuffer(0x9deb60, 0xc8200bc000, 0x9dfbe0, 0xc8200440a8, 0x0, 0x0, 0x0, 0xc82031a178, 0x0, 0x0)
        /home/matt/gotip/src/io/io.go:391 +0x306
io.Copy(0x9deb60, 0xc8200bc000, 0x9dfbe0, 0xc8200440a8, 0x7681c0, 0xc82031a120, 0xc820042f98)
        /home/matt/gotip/src/io/io.go:367 +0x5a
os/exec.(*Cmd).writerDescriptor.func1(0x7681c0, 0xc82031a120)
        /home/matt/gotip/src/os/exec/exec.go:236 +0x43
os/exec.(*Cmd).Start.func1(0xc8203e2140, 0xc8200fc200)
        /home/matt/gotip/src/os/exec/exec.go:344 +0x20
created by os/exec.(*Cmd).Start
        /home/matt/gotip/src/os/exec/exec.go:345 +0x4cd

rax    0xca
rbx    0xa068f0
rcx    0x4c9ee3
rdx    0x0
rdi    0xa075d0
rsi    0x0
rbp    0x0
rsp    0x7fff1cbeaa60
r8     0x0
r9     0x0
r10    0x0
r11    0x286
r12    0xc8201fa068
r13    0x1
r14    0xc8200885a0
r15    0x0
rip    0x4c9ee1
rflags 0x286
cs     0x33
fs     0x0
gs     0x0

@ianlancetaylor ianlancetaylor modified the milestones: Go1.7, Unplanned Apr 11, 2016
@josharian
Copy link
Contributor

Please try instead:

$ /home/matt/gotip/bin/go tool compile file1.go file2.go

and get a stack trace from that. Most of the stack trace pasted is from the go tool, not from the compiler.

Also, if possible, try generating a 1k or 5k or 10k or 50k or 100k line slice literal and see whether it completes, albeit slowly. If so, we could get a cpu profile out.

If I had to guess, I'd say that the culprit is CSE, and that this is going to be a duplicate of #15112.

@mzimmerman
Copy link
Author

Steps to reproduce:

git clone https://gist.github.com/mzimmerman/ad986f306eb71e95e9730436756caf33 fail
cd fail
sh makeGroup.sh 50000 | cat topgroup.go - > fail.go && echo "}" >> fail.go && time go tool compile fail.go

50000 map entries seems to be the tipping point for me on my hardware at least. It was successful at 45000 although it took 3m10s to compile.

My apologies, it wasn't a slice literal but a map[string]struct{string,int,[]string} literal
go version devel +944a085 Tue Apr 12 07:25:11 2016 +0000 linux/amd64 does seem like it will successfully compile it although on makeGroup.sh 100000 it ran for 20 minutes before I killed it. Trying on 50000 too.

@josharian
Copy link
Contributor

Thanks! I have some WIP for #15112 that I'll try out on this as well. May take me a day or three.

@mzimmerman
Copy link
Author

Great, thank you. +944a085 did compile a 50000 entry version in 85 minutes :)

@gopherbot
Copy link

CL https://golang.org/cl/21937 mentions this issue.

gopherbot pushed a commit that referenced this issue Apr 13, 2016
runtime.newobject never returns the same thing twice,
so the resulting value will never be a common subexpression.

This helps when compiling large static data structures
that include pointers, such as maps and slices.
No clear performance impact on other code. (See below.)

For the code in issue #15112:

Before:
  real	1m14.238s
  user	1m18.985s
  sys	0m0.787s

After:
  real	0m47.172s
  user	0m52.248s
  sys	0m0.767s

For the code in issue #15235, size 10k:

Before:
  real	0m44.916s
  user	0m46.577s
  sys	0m0.304s

After:
  real	0m7.703s
  user	0m9.041s
  sys	0m0.316s

Still more work to be done, particularly for #15112.

Updates #15112
Updates #15235


name       old time/op      new time/op      delta
Template        330ms ±11%       333ms ±13%    ~           (p=0.749 n=20+19)
Unicode         148ms ± 6%       152ms ± 8%    ~           (p=0.072 n=18+20)
GoTypes         1.01s ± 7%       1.01s ± 3%    ~           (p=0.583 n=20+20)
Compiler        5.04s ± 2%       5.06s ± 2%    ~           (p=0.314 n=20+20)

name       old user-ns/op   new user-ns/op   delta
Template   444user-ms ±11%  445user-ms ±10%    ~           (p=0.738 n=20+20)
Unicode    215user-ms ± 5%  218user-ms ± 5%    ~           (p=0.239 n=18+18)
GoTypes    1.45user-s ± 3%  1.45user-s ± 4%    ~           (p=0.620 n=20+20)
Compiler   7.23user-s ± 2%  7.22user-s ± 2%    ~           (p=0.901 n=20+19)

name       old alloc/op     new alloc/op     delta
Template       55.0MB ± 0%      55.0MB ± 0%    ~           (p=0.547 n=20+20)
Unicode        37.6MB ± 0%      37.6MB ± 0%    ~           (p=0.301 n=20+20)
GoTypes         177MB ± 0%       177MB ± 0%    ~           (p=0.065 n=20+19)
Compiler        798MB ± 0%       797MB ± 0%  -0.05%        (p=0.000 n=19+20)

name       old allocs/op    new allocs/op    delta
Template         492k ± 0%        493k ± 0%  +0.03%        (p=0.030 n=20+20)
Unicode          377k ± 0%        377k ± 0%    ~           (p=0.423 n=20+19)
GoTypes         1.40M ± 0%       1.40M ± 0%    ~           (p=0.102 n=20+20)
Compiler        5.53M ± 0%       5.53M ± 0%    ~           (p=0.094 n=17+18)

name       old text-bytes   new text-bytes   delta
HelloSize        561k ± 0%        561k ± 0%    ~     (all samples are equal)
CmdGoSize       6.13M ± 0%       6.13M ± 0%    ~     (all samples are equal)

name       old data-bytes   new data-bytes   delta
HelloSize        128k ± 0%        128k ± 0%    ~     (all samples are equal)
CmdGoSize        306k ± 0%        306k ± 0%    ~     (all samples are equal)

name       old exe-bytes    new exe-bytes    delta
HelloSize        905k ± 0%        905k ± 0%    ~     (all samples are equal)
CmdGoSize       9.64M ± 0%       9.64M ± 0%    ~     (all samples are equal)

Change-Id: Id774e2901d7701a3ec7a1c1d1cf1d9327a4107fc
Reviewed-on: https://go-review.googlesource.com/21937
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Todd Neal <todd@tneal.org>
@josharian
Copy link
Contributor

If you would, please give tip a try on your private code. CSE is still the bottleneck, but it should be much faster than it was.

I don't see any clear further steps on this, so if the performance is workable for you, please close this issue. If not, leave it open and add updated performance numbers, and perhaps someone else will take it from here.

@mzimmerman
Copy link
Author

Wow, great change! I'm now compiling my private code successfully in 1m21s and the 50000 sample version compiles in 5m32s!

Great work! 85 to 5 :) Thank you!

@golang golang locked and limited conversation to collaborators Apr 13, 2017
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

5 participants