github.com/cockroachdb/pebble@v1.1.2/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  }