From: Russ Cox Date: Fri, 3 Oct 2014 19:33:29 +0000 (-0400) Subject: runtime: clear sg.selectdone before saving in SudoG cache X-Git-Tag: go1.4beta1~204 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=13da3608453f7d50c0c810d5a0df79691bca8b64;p=gostls13.git runtime: clear sg.selectdone before saving in SudoG cache Removes another dangling pointer that might cause a memory leak in 1.4 or crash the GC in 1.5. LGTM=rlh R=golang-codereviews CC=golang-codereviews, iant, khr, r, rlh https://golang.org/cl/150520043 --- diff --git a/src/runtime/proc.go b/src/runtime/proc.go index 76e3ff8851..5b8c7d8ae9 100644 --- a/src/runtime/proc.go +++ b/src/runtime/proc.go @@ -174,6 +174,9 @@ func releaseSudog(s *sudog) { if s.elem != nil { gothrow("runtime: sudog with non-nil elem") } + if s.selectdone != nil { + gothrow("runtime: sudog with non-nil selectdone") + } gp := getg() if gp.param != nil { gothrow("runtime: releaseSudog with non-nil gp.param") diff --git a/src/runtime/select.go b/src/runtime/select.go index 1bcea8c4b4..9de057b871 100644 --- a/src/runtime/select.go +++ b/src/runtime/select.go @@ -377,8 +377,14 @@ loop: // iterating through the linked list they are in reverse order. cas = nil sglist = gp.waiting - // Clear all elem before unlinking from gp.waiting. + // Clear all selectdone and elem before unlinking from gp.waiting. + // They must be cleared before being put back into the sudog cache. + // Clear before unlinking, because if a stack copy happens after the unlink, + // they will not be updated, they will be left pointing to the old stack, + // which creates dangling pointers, which may be detected by the + // garbage collector. for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink { + sg1.selectdone = nil sg1.elem = nil } gp.waiting = nil