mirror of
https://github.com/golang/go
synced 2024-11-19 14:54:43 -07:00
[dev.garbage] runtime: make sure G.param and SudoG.elem do not hold stale pointers
In old conservative Go, this could cause memory leaks. A new pickier collector might reasonably crash when it saw one of these. LGTM=rlh R=rlh CC=golang-codereviews https://golang.org/cl/147480043
This commit is contained in:
parent
fdb0cc6e7b
commit
a3630c9e44
@ -140,10 +140,11 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
|
||||
unlock(&c.lock)
|
||||
|
||||
recvg := sg.g
|
||||
recvg.param = unsafe.Pointer(sg)
|
||||
if sg.elem != nil {
|
||||
memmove(unsafe.Pointer(sg.elem), ep, uintptr(c.elemsize))
|
||||
sg.elem = nil
|
||||
}
|
||||
recvg.param = unsafe.Pointer(sg)
|
||||
if sg.releasetime != 0 {
|
||||
sg.releasetime = cputicks()
|
||||
}
|
||||
@ -179,6 +180,7 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
|
||||
}
|
||||
panic("send on closed channel")
|
||||
}
|
||||
gp.param = nil
|
||||
if mysg.releasetime > 0 {
|
||||
blockevent(int64(mysg.releasetime)-t0, 2)
|
||||
}
|
||||
@ -278,6 +280,7 @@ func closechan(c *hchan) {
|
||||
break
|
||||
}
|
||||
gp := sg.g
|
||||
sg.elem = nil
|
||||
gp.param = nil
|
||||
if sg.releasetime != 0 {
|
||||
sg.releasetime = cputicks()
|
||||
@ -292,6 +295,7 @@ func closechan(c *hchan) {
|
||||
break
|
||||
}
|
||||
gp := sg.g
|
||||
sg.elem = nil
|
||||
gp.param = nil
|
||||
if sg.releasetime != 0 {
|
||||
sg.releasetime = cputicks()
|
||||
@ -372,6 +376,7 @@ func chanrecv(t *chantype, c *hchan, ep unsafe.Pointer, block bool) (selected, r
|
||||
if ep != nil {
|
||||
memmove(ep, sg.elem, uintptr(c.elemsize))
|
||||
}
|
||||
sg.elem = nil
|
||||
gp := sg.g
|
||||
gp.param = unsafe.Pointer(sg)
|
||||
if sg.releasetime != 0 {
|
||||
@ -409,9 +414,11 @@ func chanrecv(t *chantype, c *hchan, ep unsafe.Pointer, block bool) (selected, r
|
||||
if mysg.releasetime > 0 {
|
||||
blockevent(mysg.releasetime-t0, 2)
|
||||
}
|
||||
haveData := gp.param != nil
|
||||
gp.param = nil
|
||||
releaseSudog(mysg)
|
||||
|
||||
if gp.param != nil {
|
||||
if haveData {
|
||||
// a sender sent us some data. It already wrote to ep.
|
||||
selected = true
|
||||
received = true
|
||||
|
@ -148,6 +148,9 @@ func acquireSudog() *sudog {
|
||||
c := gomcache()
|
||||
s := c.sudogcache
|
||||
if s != nil {
|
||||
if s.elem != nil {
|
||||
gothrow("acquireSudog: found s.elem != nil in cache")
|
||||
}
|
||||
c.sudogcache = s.next
|
||||
return s
|
||||
}
|
||||
@ -162,12 +165,22 @@ func acquireSudog() *sudog {
|
||||
// which keeps the garbage collector from being invoked.
|
||||
mp := acquirem()
|
||||
p := new(sudog)
|
||||
if p.elem != nil {
|
||||
gothrow("acquireSudog: found p.elem != nil after new")
|
||||
}
|
||||
releasem(mp)
|
||||
return p
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func releaseSudog(s *sudog) {
|
||||
if s.elem != nil {
|
||||
gothrow("runtime: sudog with non-nil elem")
|
||||
}
|
||||
gp := getg()
|
||||
if gp.param != nil {
|
||||
gothrow("runtime: releaseSudog with non-nil gp.param")
|
||||
}
|
||||
c := gomcache()
|
||||
s.next = c.sudogcache
|
||||
c.sudogcache = s
|
||||
|
@ -368,6 +368,7 @@ loop:
|
||||
// someone woke us up
|
||||
sellock(sel)
|
||||
sg = (*sudog)(gp.param)
|
||||
gp.param = nil
|
||||
|
||||
// pass 3 - dequeue from unsuccessful chans
|
||||
// otherwise they stack up on quiet channels
|
||||
@ -376,6 +377,10 @@ loop:
|
||||
// iterating through the linked list they are in reverse order.
|
||||
cas = nil
|
||||
sglist = gp.waiting
|
||||
// Clear all elem before unlinking from gp.waiting.
|
||||
for sg1 := gp.waiting; sg1 != nil; sg1 = sg1.waitlink {
|
||||
sg1.elem = nil
|
||||
}
|
||||
gp.waiting = nil
|
||||
for i := int(sel.ncase) - 1; i >= 0; i-- {
|
||||
k = &scases[pollorder[i]]
|
||||
@ -506,6 +511,7 @@ syncrecv:
|
||||
if cas.elem != nil {
|
||||
memmove(cas.elem, sg.elem, uintptr(c.elemsize))
|
||||
}
|
||||
sg.elem = nil
|
||||
gp = sg.g
|
||||
gp.param = unsafe.Pointer(sg)
|
||||
if sg.releasetime != 0 {
|
||||
@ -541,6 +547,7 @@ syncsend:
|
||||
if sg.elem != nil {
|
||||
memmove(sg.elem, cas.elem, uintptr(c.elemsize))
|
||||
}
|
||||
sg.elem = nil
|
||||
gp = sg.g
|
||||
gp.param = unsafe.Pointer(sg)
|
||||
if sg.releasetime != 0 {
|
||||
|
@ -168,6 +168,7 @@ func (root *semaRoot) dequeue(s *sudog) {
|
||||
} else {
|
||||
root.head = s.next
|
||||
}
|
||||
s.elem = nil
|
||||
s.next = nil
|
||||
s.prev = nil
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user