1 // Copyright 2011 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.
19 func TestCPUProfile(t *testing.T) {
22 out, err := exec.Command("uname", "-a").CombinedOutput()
27 t.Logf("uname -a: %v", vers)
28 // Lion uses "Darwin Kernel Version 11".
29 if strings.Contains(vers, "Darwin Kernel Version 10") && strings.Contains(vers, "RELEASE_X86_64") {
30 t.Logf("skipping test on known-broken kernel (64-bit Leopard / Snow Leopard)")
38 buf := make([]byte, 100000)
40 if err := StartCPUProfile(&prof); err != nil {
43 // This loop takes about a quarter second on a 2 GHz laptop.
44 // We only need to get one 100 Hz clock tick, so we've got
45 // a 25x safety buffer.
46 for i := 0; i < 1000; i++ {
47 crc32.ChecksumIEEE(buf)
51 // Convert []byte to []uintptr.
53 l := len(bytes) / int(unsafe.Sizeof(uintptr(0)))
54 val := *(*[]uintptr)(unsafe.Pointer(&bytes))
58 t.Fatalf("profile too short: %#x", val)
62 hd, val, tl := val[:5], val[5:l-3], val[l-3:]
63 fmt.Println(hd, val, tl)
64 if hd[0] != 0 || hd[1] != 3 || hd[2] != 0 || hd[3] != 1e6/100 || hd[4] != 0 {
65 t.Fatalf("unexpected header %#x", hd)
68 if tl[0] != 0 || tl[1] != 1 || tl[2] != 0 {
69 t.Fatalf("malformed end-of-data marker %#x", tl)
72 // Check that profile is well formed and contains ChecksumIEEE.
75 if len(val) < 2 || val[0] < 1 || val[1] < 1 || uintptr(len(val)) < 2+val[1] {
76 t.Fatalf("malformed profile. leftover: %#x", val)
78 for _, pc := range val[2 : 2+val[1]] {
79 f := runtime.FuncForPC(pc)
83 if strings.Contains(f.Name(), "ChecksumIEEE") ||
84 (strings.Contains(f.Name(), "update") && strings.Contains(f.Name(), "crc32")) {
92 t.Fatal("did not find ChecksumIEEE in the profile")