Source file src/runtime/debug/heapdump_test.go

     1  // Copyright 2014 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  package debug_test
     6  
     7  import (
     8  	"os"
     9  	"runtime"
    10  	. "runtime/debug"
    11  	"testing"
    12  )
    13  
    14  func TestWriteHeapDumpNonempty(t *testing.T) {
    15  	if runtime.GOOS == "js" {
    16  		t.Skipf("WriteHeapDump is not available on %s.", runtime.GOOS)
    17  	}
    18  	f, err := os.CreateTemp("", "heapdumptest")
    19  	if err != nil {
    20  		t.Fatalf("TempFile failed: %v", err)
    21  	}
    22  	defer os.Remove(f.Name())
    23  	defer f.Close()
    24  	WriteHeapDump(f.Fd())
    25  	fi, err := f.Stat()
    26  	if err != nil {
    27  		t.Fatalf("Stat failed: %v", err)
    28  	}
    29  	const minSize = 1
    30  	if size := fi.Size(); size < minSize {
    31  		t.Fatalf("Heap dump size %d bytes, expected at least %d bytes", size, minSize)
    32  	}
    33  }
    34  
    35  type Obj struct {
    36  	x, y int
    37  }
    38  
    39  func objfin(x *Obj) {
    40  	//println("finalized", x)
    41  }
    42  
    43  func TestWriteHeapDumpFinalizers(t *testing.T) {
    44  	if runtime.GOOS == "js" {
    45  		t.Skipf("WriteHeapDump is not available on %s.", runtime.GOOS)
    46  	}
    47  	f, err := os.CreateTemp("", "heapdumptest")
    48  	if err != nil {
    49  		t.Fatalf("TempFile failed: %v", err)
    50  	}
    51  	defer os.Remove(f.Name())
    52  	defer f.Close()
    53  
    54  	// bug 9172: WriteHeapDump couldn't handle more than one finalizer
    55  	println("allocating objects")
    56  	x := &Obj{}
    57  	runtime.SetFinalizer(x, objfin)
    58  	y := &Obj{}
    59  	runtime.SetFinalizer(y, objfin)
    60  
    61  	// Trigger collection of x and y, queueing of their finalizers.
    62  	println("starting gc")
    63  	runtime.GC()
    64  
    65  	// Make sure WriteHeapDump doesn't fail with multiple queued finalizers.
    66  	println("starting dump")
    67  	WriteHeapDump(f.Fd())
    68  	println("done dump")
    69  }
    70  
    71  type G[T any] struct{}
    72  type I interface {
    73  	M()
    74  }
    75  
    76  //go:noinline
    77  func (g G[T]) M() {}
    78  
    79  var dummy I = G[int]{}
    80  var dummy2 I = G[G[int]]{}
    81  
    82  func TestWriteHeapDumpTypeName(t *testing.T) {
    83  	if runtime.GOOS == "js" {
    84  		t.Skipf("WriteHeapDump is not available on %s.", runtime.GOOS)
    85  	}
    86  	f, err := os.CreateTemp("", "heapdumptest")
    87  	if err != nil {
    88  		t.Fatalf("TempFile failed: %v", err)
    89  	}
    90  	defer os.Remove(f.Name())
    91  	defer f.Close()
    92  	WriteHeapDump(f.Fd())
    93  	dummy.M()
    94  	dummy2.M()
    95  }
    96  

View as plain text