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 6 7 import ( 8 "io/ioutil" 9 "os" 10 "runtime" 11 "testing" 12 ) 13 14 func TestWriteHeapDumpNonempty(t *testing.T) { 15 if runtime.GOOS == "nacl" { 16 t.Skip("WriteHeapDump is not available on NaCl.") 17 } 18 f, err := ioutil.TempFile("", "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 == "nacl" { 45 t.Skip("WriteHeapDump is not available on NaCl.") 46 } 47 f, err := ioutil.TempFile("", "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