github.com/cockroachdb/pebble@v1.1.1-0.20240513155919-3622ade60459/internal/cache/value_invariants.go (about) 1 // Copyright 2020 The LevelDB-Go and Pebble Authors. All rights reserved. Use 2 // of this source code is governed by a BSD-style license that can be found in 3 // the LICENSE file. 4 5 //go:build (invariants && !race) || (tracing && !race) 6 // +build invariants,!race tracing,!race 7 8 package cache 9 10 import ( 11 "fmt" 12 "os" 13 14 "github.com/cockroachdb/pebble/internal/invariants" 15 "github.com/cockroachdb/pebble/internal/manual" 16 ) 17 18 // newValue creates a Value with a manually managed buffer of size n. 19 // 20 // This definition of newValue is used when either the "invariants" or 21 // "tracing" build tags are specified. It hooks up a finalizer to the returned 22 // Value that checks for memory leaks when the GC determines the Value is no 23 // longer reachable. 24 func newValue(n int) *Value { 25 if n == 0 { 26 return nil 27 } 28 b := manual.New(n) 29 v := &Value{buf: b} 30 v.ref.init(1) 31 // Note: this is a no-op if invariants and tracing are disabled or race is 32 // enabled. 33 invariants.SetFinalizer(v, func(obj interface{}) { 34 v := obj.(*Value) 35 if v.buf != nil { 36 fmt.Fprintf(os.Stderr, "%p: cache value was not freed: refs=%d\n%s", 37 v, v.refs(), v.ref.traces()) 38 os.Exit(1) 39 } 40 }) 41 return v 42 } 43 44 func (v *Value) free() { 45 // When "invariants" are enabled set the value contents to 0xff in order to 46 // cache use-after-free bugs. 47 for i := range v.buf { 48 v.buf[i] = 0xff 49 } 50 manual.Free(v.buf) 51 // Setting Value.buf to nil is needed for correctness of the leak checking 52 // that is performed when the "invariants" or "tracing" build tags are 53 // enabled. 54 v.buf = nil 55 }