1// Copyright 2009 The Go Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// Garbage collector: finalizers and block profiling. 6 7package runtime 8 9import ( 10 "runtime/internal/atomic" 11 "runtime/internal/sys" 12 "unsafe" 13) 14 15// finblock is an array of finalizers to be executed. finblocks are 16// arranged in a linked list for the finalizer queue. 17// 18// finblock is allocated from non-GC'd memory, so any heap pointers 19// must be specially handled. GC currently assumes that the finalizer 20// queue does not grow during marking (but it can shrink). 21// 22//go:notinheap 23type finblock struct { 24 alllink *finblock 25 next *finblock 26 cnt uint32 27 _ int32 28 fin [(_FinBlockSize - 2*sys.PtrSize - 2*4) / unsafe.Sizeof(finalizer{})]finalizer 29} 30 31var finlock mutex // protects the following variables 32var fing *g // goroutine that runs finalizers 33var finq *finblock // list of finalizers that are to be executed 34var finc *finblock // cache of free blocks 35var finptrmask [_FinBlockSize / sys.PtrSize / 8]byte 36var fingwait bool 37var fingwake bool 38var allfin *finblock // list of all blocks 39 40// NOTE: Layout known to queuefinalizer. 41type finalizer struct { 42 fn *funcval // function to call (may be a heap pointer) 43 arg unsafe.Pointer // ptr to object (may be a heap pointer) 44 ft *functype // type of fn (unlikely, but may be a heap pointer) 45 ot *ptrtype // type of ptr to object (may be a heap pointer) 46} 47 48func queuefinalizer(p unsafe.Pointer, fn *funcval, ft *functype, ot *ptrtype) { 49 if gcphase != _GCoff { 50 // Currently we assume that the finalizer queue won't 51 // grow during marking so we don't have to rescan it 52 // during mark termination. If we ever need to lift 53 // this assumption, we can do it by adding the 54 // necessary barriers to queuefinalizer (which it may 55 // have automatically). 56 throw("queuefinalizer during GC") 57 } 58 59 lock(&finlock) 60 if finq == nil || finq.cnt == uint32(len(finq.fin)) { 61 if finc == nil { 62 finc = (*finblock)(persistentalloc(_FinBlockSize, 0, &memstats.gc_sys)) 63 finc.alllink = allfin 64 allfin = finc 65 if finptrmask[0] == 0 { 66 // Build pointer mask for Finalizer array in block. 67 // We allocate values of type finalizer in 68 // finblock values. Since these values are 69 // allocated by persistentalloc, they require 70 // special scanning during GC. finptrmask is a 71 // pointer mask to use while scanning. 72 // Since all the values in finalizer are 73 // pointers, just turn all bits on. 74 for i := range finptrmask { 75 finptrmask[i] = 0xff 76 } 77 } 78 } 79 block := finc 80 finc = block.next 81 block.next = finq 82 finq = block 83 } 84 f := &finq.fin[finq.cnt] 85 atomic.Xadd(&finq.cnt, +1) // Sync with markroots 86 f.fn = fn 87 f.ft = ft 88 f.ot = ot 89 f.arg = p 90 fingwake = true 91 unlock(&finlock) 92} 93 94//go:nowritebarrier 95func iterate_finq(callback func(*funcval, unsafe.Pointer, *functype, *ptrtype)) { 96 for fb := allfin; fb != nil; fb = fb.alllink { 97 for i := uint32(0); i < fb.cnt; i++ { 98 f := &fb.fin[i] 99 callback(f.fn, f.arg, f.ft, f.ot) 100 } 101 } 102} 103 104func wakefing() *g { 105 var res *g 106 lock(&finlock) 107 if fingwait && fingwake { 108 fingwait = false 109 fingwake = false 110 res = fing 111 } 112 unlock(&finlock) 113 return res 114} 115 116var ( 117 fingCreate uint32 118) 119 120func createfing() { 121 // start the finalizer goroutine exactly once 122 if fingCreate == 0 && atomic.Cas(&fingCreate, 0, 1) { 123 expectSystemGoroutine() 124 go runfinq() 125 } 126} 127 128// This is the goroutine that runs all of the finalizers 129func runfinq() { 130 setSystemGoroutine() 131 132 var ( 133 ef eface 134 ifac iface 135 ) 136 137 gp := getg() 138 gp.isFinalizerGoroutine = true 139 for { 140 lock(&finlock) 141 fb := finq 142 finq = nil 143 if fb == nil { 144 fing = gp 145 fingwait = true 146 goparkunlock(&finlock, waitReasonFinalizerWait, traceEvGoBlock, 1) 147 continue 148 } 149 unlock(&finlock) 150 for fb != nil { 151 for i := fb.cnt; i > 0; i-- { 152 f := &fb.fin[i-1] 153 154 if f.ft == nil { 155 throw("missing type in runfinq") 156 } 157 fint := f.ft.in[0] 158 var param unsafe.Pointer 159 switch fint.kind & kindMask { 160 case kindPtr: 161 // direct use of pointer 162 param = unsafe.Pointer(&f.arg) 163 case kindInterface: 164 ityp := (*interfacetype)(unsafe.Pointer(fint)) 165 if len(ityp.methods) == 0 { 166 // set up with empty interface 167 ef._type = &f.ot.typ 168 ef.data = f.arg 169 param = unsafe.Pointer(&ef) 170 } else { 171 // convert to interface with methods 172 // this conversion is guaranteed to succeed - we checked in SetFinalizer 173 ifac.tab = getitab(fint, &f.ot.typ, true) 174 ifac.data = f.arg 175 param = unsafe.Pointer(&ifac) 176 } 177 default: 178 throw("bad kind in runfinq") 179 } 180 // This is not a system goroutine while 181 // running the actual finalizer. 182 // This matters because we want this 183 // goroutine to appear in a stack dump 184 // if the finalizer crashes. 185 // The gc toolchain handles this using 186 // a global variable fingRunning, 187 // but we don't need that. 188 gp.isSystemGoroutine = false 189 reflectcall(f.ft, f.fn, false, false, ¶m, nil) 190 gp.isSystemGoroutine = true 191 192 // Drop finalizer queue heap references 193 // before hiding them from markroot. 194 // This also ensures these will be 195 // clear if we reuse the finalizer. 196 f.fn = nil 197 f.arg = nil 198 f.ot = nil 199 atomic.Store(&fb.cnt, i-1) 200 } 201 next := fb.next 202 lock(&finlock) 203 fb.next = finc 204 finc = fb 205 unlock(&finlock) 206 fb = next 207 } 208 } 209} 210 211// SetFinalizer sets the finalizer associated with obj to the provided 212// finalizer function. When the garbage collector finds an unreachable block 213// with an associated finalizer, it clears the association and runs 214// finalizer(obj) in a separate goroutine. This makes obj reachable again, 215// but now without an associated finalizer. Assuming that SetFinalizer 216// is not called again, the next time the garbage collector sees 217// that obj is unreachable, it will free obj. 218// 219// SetFinalizer(obj, nil) clears any finalizer associated with obj. 220// 221// The argument obj must be a pointer to an object allocated by calling 222// new, by taking the address of a composite literal, or by taking the 223// address of a local variable. 224// The argument finalizer must be a function that takes a single argument 225// to which obj's type can be assigned, and can have arbitrary ignored return 226// values. If either of these is not true, SetFinalizer may abort the 227// program. 228// 229// Finalizers are run in dependency order: if A points at B, both have 230// finalizers, and they are otherwise unreachable, only the finalizer 231// for A runs; once A is freed, the finalizer for B can run. 232// If a cyclic structure includes a block with a finalizer, that 233// cycle is not guaranteed to be garbage collected and the finalizer 234// is not guaranteed to run, because there is no ordering that 235// respects the dependencies. 236// 237// The finalizer is scheduled to run at some arbitrary time after the 238// program can no longer reach the object to which obj points. 239// There is no guarantee that finalizers will run before a program exits, 240// so typically they are useful only for releasing non-memory resources 241// associated with an object during a long-running program. 242// For example, an os.File object could use a finalizer to close the 243// associated operating system file descriptor when a program discards 244// an os.File without calling Close, but it would be a mistake 245// to depend on a finalizer to flush an in-memory I/O buffer such as a 246// bufio.Writer, because the buffer would not be flushed at program exit. 247// 248// It is not guaranteed that a finalizer will run if the size of *obj is 249// zero bytes. 250// 251// It is not guaranteed that a finalizer will run for objects allocated 252// in initializers for package-level variables. Such objects may be 253// linker-allocated, not heap-allocated. 254// 255// A finalizer may run as soon as an object becomes unreachable. 256// In order to use finalizers correctly, the program must ensure that 257// the object is reachable until it is no longer required. 258// Objects stored in global variables, or that can be found by tracing 259// pointers from a global variable, are reachable. For other objects, 260// pass the object to a call of the KeepAlive function to mark the 261// last point in the function where the object must be reachable. 262// 263// For example, if p points to a struct that contains a file descriptor d, 264// and p has a finalizer that closes that file descriptor, and if the last 265// use of p in a function is a call to syscall.Write(p.d, buf, size), then 266// p may be unreachable as soon as the program enters syscall.Write. The 267// finalizer may run at that moment, closing p.d, causing syscall.Write 268// to fail because it is writing to a closed file descriptor (or, worse, 269// to an entirely different file descriptor opened by a different goroutine). 270// To avoid this problem, call runtime.KeepAlive(p) after the call to 271// syscall.Write. 272// 273// A single goroutine runs all finalizers for a program, sequentially. 274// If a finalizer must run for a long time, it should do so by starting 275// a new goroutine. 276func SetFinalizer(obj interface{}, finalizer interface{}) { 277 if debug.sbrk != 0 { 278 // debug.sbrk never frees memory, so no finalizers run 279 // (and we don't have the data structures to record them). 280 return 281 } 282 e := efaceOf(&obj) 283 etyp := e._type 284 if etyp == nil { 285 throw("runtime.SetFinalizer: first argument is nil") 286 } 287 if etyp.kind&kindMask != kindPtr { 288 throw("runtime.SetFinalizer: first argument is " + etyp.string() + ", not pointer") 289 } 290 ot := (*ptrtype)(unsafe.Pointer(etyp)) 291 if ot.elem == nil { 292 throw("nil elem type!") 293 } 294 295 // find the containing object 296 base, _, _ := findObject(uintptr(e.data), 0, 0, false) 297 298 if base == 0 { 299 // 0-length objects are okay. 300 if e.data == unsafe.Pointer(&zerobase) { 301 return 302 } 303 304 // Global initializers might be linker-allocated. 305 // var Foo = &Object{} 306 // func main() { 307 // runtime.SetFinalizer(Foo, nil) 308 // } 309 // The relevant segments are: noptrdata, data, bss, noptrbss. 310 // We cannot assume they are in any order or even contiguous, 311 // due to external linking. 312 // 313 // For gccgo we have no reliable way to detect them, 314 // so we just return. 315 return 316 } 317 318 if uintptr(e.data) != base { 319 // As an implementation detail we allow to set finalizers for an inner byte 320 // of an object if it could come from tiny alloc (see mallocgc for details). 321 if ot.elem == nil || ot.elem.ptrdata != 0 || ot.elem.size >= maxTinySize { 322 throw("runtime.SetFinalizer: pointer not at beginning of allocated block") 323 } 324 } 325 326 f := efaceOf(&finalizer) 327 ftyp := f._type 328 if ftyp == nil { 329 // switch to system stack and remove finalizer 330 systemstack(func() { 331 removefinalizer(e.data) 332 }) 333 return 334 } 335 336 if ftyp.kind&kindMask != kindFunc { 337 throw("runtime.SetFinalizer: second argument is " + ftyp.string() + ", not a function") 338 } 339 ft := (*functype)(unsafe.Pointer(ftyp)) 340 if ft.dotdotdot { 341 throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string() + " because dotdotdot") 342 } 343 if len(ft.in) != 1 { 344 throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string()) 345 } 346 fint := ft.in[0] 347 switch { 348 case fint == etyp: 349 // ok - same type 350 goto okarg 351 case fint.kind&kindMask == kindPtr: 352 if (fint.uncommontype == nil || etyp.uncommontype == nil) && (*ptrtype)(unsafe.Pointer(fint)).elem == ot.elem { 353 // ok - not same type, but both pointers, 354 // one or the other is unnamed, and same element type, so assignable. 355 goto okarg 356 } 357 case fint.kind&kindMask == kindInterface: 358 ityp := (*interfacetype)(unsafe.Pointer(fint)) 359 if len(ityp.methods) == 0 { 360 // ok - satisfies empty interface 361 goto okarg 362 } 363 if getitab(fint, etyp, true) == nil { 364 goto okarg 365 } 366 } 367 throw("runtime.SetFinalizer: cannot pass " + etyp.string() + " to finalizer " + ftyp.string()) 368okarg: 369 // make sure we have a finalizer goroutine 370 createfing() 371 372 systemstack(func() { 373 data := f.data 374 if !isDirectIface(ftyp) { 375 data = *(*unsafe.Pointer)(data) 376 } 377 if !addfinalizer(e.data, (*funcval)(data), ft, ot) { 378 throw("runtime.SetFinalizer: finalizer already set") 379 } 380 }) 381} 382 383// Mark KeepAlive as noinline so that it is easily detectable as an intrinsic. 384//go:noinline 385 386// KeepAlive marks its argument as currently reachable. 387// This ensures that the object is not freed, and its finalizer is not run, 388// before the point in the program where KeepAlive is called. 389// 390// A very simplified example showing where KeepAlive is required: 391// type File struct { d int } 392// d, err := syscall.Open("/file/path", syscall.O_RDONLY, 0) 393// // ... do something if err != nil ... 394// p := &File{d} 395// runtime.SetFinalizer(p, func(p *File) { syscall.Close(p.d) }) 396// var buf [10]byte 397// n, err := syscall.Read(p.d, buf[:]) 398// // Ensure p is not finalized until Read returns. 399// runtime.KeepAlive(p) 400// // No more uses of p after this point. 401// 402// Without the KeepAlive call, the finalizer could run at the start of 403// syscall.Read, closing the file descriptor before syscall.Read makes 404// the actual system call. 405func KeepAlive(x interface{}) { 406 // Introduce a use of x that the compiler can't eliminate. 407 // This makes sure x is alive on entry. We need x to be alive 408 // on entry for "defer runtime.KeepAlive(x)"; see issue 21402. 409 if cgoAlwaysFalse { 410 println(x) 411 } 412} 413