mirror of
https://github.com/golang/go
synced 2024-11-11 21:20:21 -07:00
cmd: refresh cmd/vendor to match 'go mod vendor'
This change preserves the maximum versions from cmd/vendor/vendor.json where feasible, but bumps the versions of x/sys (for CL 162987) and x/tools (for CL 162989 and CL 160837) so that 'go test all' passes in module mode when run from a working directory in src/cmd. A small change to cmd/vet (not vendored) was necessary to preserve its flag behavior given a pristine copy of x/tools; see CL 162989 for more detail. This change was generated by running 'go mod vendor' at CL 164622. (Welcoooome to the fuuuuuture!) Updates #30228 Updates #30241 Change-Id: I889590318dc857d4a6e20c3023d09a27128d8255 Reviewed-on: https://go-review.googlesource.com/c/go/+/164618 Run-TryBot: Bryan C. Mills <bcmills@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
parent
486ca37b14
commit
756a69c6c9
@ -48,43 +48,33 @@ go src=..
|
||||
pprof
|
||||
internal
|
||||
binutils
|
||||
testdata
|
||||
+
|
||||
driver
|
||||
testdata
|
||||
+
|
||||
graph
|
||||
testdata
|
||||
+
|
||||
report
|
||||
testdata
|
||||
+
|
||||
profile
|
||||
testdata
|
||||
+
|
||||
driver
|
||||
+
|
||||
graph
|
||||
+
|
||||
report
|
||||
+
|
||||
profile
|
||||
+
|
||||
ianlancetaylor
|
||||
demangle
|
||||
testdata
|
||||
+
|
||||
+
|
||||
golang.org
|
||||
x
|
||||
arch
|
||||
arm
|
||||
armasm
|
||||
testdata
|
||||
+
|
||||
+
|
||||
arm64
|
||||
arm64asm
|
||||
testdata
|
||||
+
|
||||
+
|
||||
x86
|
||||
x86asm
|
||||
testdata
|
||||
+
|
||||
+
|
||||
ppc64
|
||||
ppc64asm
|
||||
testdata
|
||||
+
|
||||
+
|
||||
archive
|
||||
tar
|
||||
testdata
|
||||
|
13
src/cmd/go.sum
Normal file
13
src/cmd/go.sum
Normal file
@ -0,0 +1,13 @@
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57 h1:eqyIo2HjKhKe/mJzTG8n4VqvLXIOEG+SLdDqX7xGtkY=
|
||||
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20180524225900-fc6590592b44 h1:pKqc8lAAA6rcwpvsephnRuZp4VHbfszZRClvqAE6Sq8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20180524225900-fc6590592b44/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045 h1:Pn8fQdvx+z1avAi7fdM2kRYWQNxGlavNDSyzrQg2SsU=
|
||||
golang.org/x/arch v0.0.0-20181203225421-5a4828bb7045/go.mod h1:cYlCBUl1MsqxdiKgmc4uh7TxZfWSFLOGSRR090WDxt8=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67 h1:ng3VDlRp5/DHpSWl02R4rM9I+8M2rhmsuLwAMmkLQWE=
|
||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/sys v0.0.0-20190225065934-cc5685c2db12 h1:Zw7eRv6INHGfu15LVRN1vrrwusJbnfJjAZn3D1VkQIE=
|
||||
golang.org/x/sys v0.0.0-20190225065934-cc5685c2db12/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3 h1:2oZsfYnKfYzL4I57uYiRFsUf0bqlLkiuw8nnj3+voUA=
|
||||
golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4=
|
25
src/cmd/vendor/README
vendored
25
src/cmd/vendor/README
vendored
@ -1,25 +0,0 @@
|
||||
How to update the vendored packages:
|
||||
|
||||
Assuming the govendor tool is available
|
||||
run the govendor tool from src/cmd directory
|
||||
|
||||
$ go get -u github.com/kardianos/govendor
|
||||
|
||||
To update packages used by cmd/pprof:
|
||||
|
||||
$ cd $GOROOT/src/cmd
|
||||
$ GOPATH=$GOROOT govendor fetch github.com/google/pprof/...
|
||||
|
||||
To update packages used by internal/objfile/*:
|
||||
|
||||
$ GOPATH=$GOROOT govendor fetch golang.org/x/arch/...
|
||||
|
||||
GOPATH=$GOROOT in the above commands is a hack to
|
||||
make govendor work and will create the .cache folder in
|
||||
$GOROOT as a side-effect. Please make sure to delete
|
||||
the directory and not to include the directory in the
|
||||
commit by accident.
|
||||
|
||||
The vendored copy of golang.org/x/tools is maintained by
|
||||
running the update-xtools.sh script in this directory,
|
||||
not by govendor.
|
7
src/cmd/vendor/github.com/google/pprof/AUTHORS
generated
vendored
Normal file
7
src/cmd/vendor/github.com/google/pprof/AUTHORS
generated
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
# This is the official list of pprof authors for copyright purposes.
|
||||
# This file is distinct from the CONTRIBUTORS files.
|
||||
# See the latter for an explanation.
|
||||
# Names should be added to this file as:
|
||||
# Name or Organization <email address>
|
||||
# The email address is not required for organizations.
|
||||
Google Inc.
|
15
src/cmd/vendor/github.com/google/pprof/CONTRIBUTORS
generated
vendored
Normal file
15
src/cmd/vendor/github.com/google/pprof/CONTRIBUTORS
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
# People who have agreed to one of the CLAs and can contribute patches.
|
||||
# The AUTHORS file lists the copyright holders; this file
|
||||
# lists people. For example, Google employees are listed here
|
||||
# but not in AUTHORS, because Google holds the copyright.
|
||||
#
|
||||
# https://developers.google.com/open-source/cla/individual
|
||||
# https://developers.google.com/open-source/cla/corporate
|
||||
#
|
||||
# Names should be added to this file as:
|
||||
# Name <email address>
|
||||
Raul Silvera <rsilvera@google.com>
|
||||
Tipp Moseley <tipp@google.com>
|
||||
Hyoun Kyu Cho <netforce@google.com>
|
||||
Martin Spier <spiermar@gmail.com>
|
||||
Taco de Wolff <tacodewolff@gmail.com>
|
392
src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils_test.go
generated
vendored
392
src/cmd/vendor/github.com/google/pprof/internal/binutils/binutils_test.go
generated
vendored
@ -1,392 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package binutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"math"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/pprof/internal/plugin"
|
||||
)
|
||||
|
||||
var testAddrMap = map[int]string{
|
||||
1000: "_Z3fooid.clone2",
|
||||
2000: "_ZNSaIiEC1Ev.clone18",
|
||||
3000: "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm",
|
||||
}
|
||||
|
||||
func functionName(level int) (name string) {
|
||||
if name = testAddrMap[level]; name != "" {
|
||||
return name
|
||||
}
|
||||
return fmt.Sprintf("fun%d", level)
|
||||
}
|
||||
|
||||
func TestAddr2Liner(t *testing.T) {
|
||||
const offset = 0x500
|
||||
|
||||
a := addr2Liner{rw: &mockAddr2liner{}, base: offset}
|
||||
for i := 1; i < 8; i++ {
|
||||
addr := i*0x1000 + offset
|
||||
s, err := a.addrInfo(uint64(addr))
|
||||
if err != nil {
|
||||
t.Fatalf("addrInfo(%#x): %v", addr, err)
|
||||
}
|
||||
if len(s) != i {
|
||||
t.Fatalf("addrInfo(%#x): got len==%d, want %d", addr, len(s), i)
|
||||
}
|
||||
for l, f := range s {
|
||||
level := (len(s) - l) * 1000
|
||||
want := plugin.Frame{Func: functionName(level), File: fmt.Sprintf("file%d", level), Line: level}
|
||||
|
||||
if f != want {
|
||||
t.Errorf("AddrInfo(%#x)[%d]: = %+v, want %+v", addr, l, f, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
s, err := a.addrInfo(0xFFFF)
|
||||
if err != nil {
|
||||
t.Fatalf("addrInfo(0xFFFF): %v", err)
|
||||
}
|
||||
if len(s) != 0 {
|
||||
t.Fatalf("AddrInfo(0xFFFF): got len==%d, want 0", len(s))
|
||||
}
|
||||
a.rw.close()
|
||||
}
|
||||
|
||||
type mockAddr2liner struct {
|
||||
output []string
|
||||
}
|
||||
|
||||
func (a *mockAddr2liner) write(s string) error {
|
||||
var lines []string
|
||||
switch s {
|
||||
case "1000":
|
||||
lines = []string{"_Z3fooid.clone2", "file1000:1000"}
|
||||
case "2000":
|
||||
lines = []string{"_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
|
||||
case "3000":
|
||||
lines = []string{"_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
|
||||
case "4000":
|
||||
lines = []string{"fun4000", "file4000:4000", "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
|
||||
case "5000":
|
||||
lines = []string{"fun5000", "file5000:5000", "fun4000", "file4000:4000", "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
|
||||
case "6000":
|
||||
lines = []string{"fun6000", "file6000:6000", "fun5000", "file5000:5000", "fun4000", "file4000:4000", "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
|
||||
case "7000":
|
||||
lines = []string{"fun7000", "file7000:7000", "fun6000", "file6000:6000", "fun5000", "file5000:5000", "fun4000", "file4000:4000", "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
|
||||
case "8000":
|
||||
lines = []string{"fun8000", "file8000:8000", "fun7000", "file7000:7000", "fun6000", "file6000:6000", "fun5000", "file5000:5000", "fun4000", "file4000:4000", "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
|
||||
case "9000":
|
||||
lines = []string{"fun9000", "file9000:9000", "fun8000", "file8000:8000", "fun7000", "file7000:7000", "fun6000", "file6000:6000", "fun5000", "file5000:5000", "fun4000", "file4000:4000", "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
|
||||
default:
|
||||
lines = []string{"??", "??:0"}
|
||||
}
|
||||
a.output = append(a.output, "0x"+s)
|
||||
a.output = append(a.output, lines...)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *mockAddr2liner) readLine() (string, error) {
|
||||
if len(a.output) == 0 {
|
||||
return "", fmt.Errorf("end of file")
|
||||
}
|
||||
next := a.output[0]
|
||||
a.output = a.output[1:]
|
||||
return next, nil
|
||||
}
|
||||
|
||||
func (a *mockAddr2liner) close() {
|
||||
}
|
||||
|
||||
func TestAddr2LinerLookup(t *testing.T) {
|
||||
const oddSizedData = `
|
||||
00001000 T 0x1000
|
||||
00002000 T 0x2000
|
||||
00003000 T 0x3000
|
||||
`
|
||||
const evenSizedData = `
|
||||
0000000000001000 T 0x1000
|
||||
0000000000002000 T 0x2000
|
||||
0000000000003000 T 0x3000
|
||||
0000000000004000 T 0x4000
|
||||
`
|
||||
for _, d := range []string{oddSizedData, evenSizedData} {
|
||||
a, err := parseAddr2LinerNM(0, bytes.NewBufferString(d))
|
||||
if err != nil {
|
||||
t.Errorf("nm parse error: %v", err)
|
||||
continue
|
||||
}
|
||||
for address, want := range map[uint64]string{
|
||||
0x1000: "0x1000",
|
||||
0x1001: "0x1000",
|
||||
0x1FFF: "0x1000",
|
||||
0x2000: "0x2000",
|
||||
0x2001: "0x2000",
|
||||
} {
|
||||
if got, _ := a.addrInfo(address); !checkAddress(got, address, want) {
|
||||
t.Errorf("%x: got %v, want %s", address, got, want)
|
||||
}
|
||||
}
|
||||
for _, unknown := range []uint64{0x0fff, 0x4001} {
|
||||
if got, _ := a.addrInfo(unknown); got != nil {
|
||||
t.Errorf("%x: got %v, want nil", unknown, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkAddress(got []plugin.Frame, address uint64, want string) bool {
|
||||
if len(got) != 1 {
|
||||
return false
|
||||
}
|
||||
return got[0].Func == want
|
||||
}
|
||||
|
||||
func TestSetTools(t *testing.T) {
|
||||
// Test that multiple calls work.
|
||||
bu := &Binutils{}
|
||||
bu.SetTools("")
|
||||
bu.SetTools("")
|
||||
}
|
||||
|
||||
func TestSetFastSymbolization(t *testing.T) {
|
||||
// Test that multiple calls work.
|
||||
bu := &Binutils{}
|
||||
bu.SetFastSymbolization(true)
|
||||
bu.SetFastSymbolization(false)
|
||||
}
|
||||
|
||||
func skipUnlessLinuxAmd64(t *testing.T) {
|
||||
if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
|
||||
t.Skip("This test only works on x86-64 Linux")
|
||||
}
|
||||
}
|
||||
|
||||
func skipUnlessDarwinAmd64(t *testing.T) {
|
||||
if runtime.GOOS != "darwin" || runtime.GOARCH != "amd64" {
|
||||
t.Skip("This test only works on x86-64 Mac")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDisasm(t *testing.T) {
|
||||
skipUnlessLinuxAmd64(t)
|
||||
bu := &Binutils{}
|
||||
insts, err := bu.Disasm(filepath.Join("testdata", "exe_linux_64"), 0, math.MaxUint64)
|
||||
if err != nil {
|
||||
t.Fatalf("Disasm: unexpected error %v", err)
|
||||
}
|
||||
mainCount := 0
|
||||
for _, x := range insts {
|
||||
if x.Function == "main" {
|
||||
mainCount++
|
||||
}
|
||||
}
|
||||
if mainCount == 0 {
|
||||
t.Error("Disasm: found no main instructions")
|
||||
}
|
||||
}
|
||||
|
||||
func findSymbol(syms []*plugin.Sym, name string) *plugin.Sym {
|
||||
for _, s := range syms {
|
||||
for _, n := range s.Name {
|
||||
if n == name {
|
||||
return s
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func TestObjFile(t *testing.T) {
|
||||
skipUnlessLinuxAmd64(t)
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
start, limit, offset uint64
|
||||
addr uint64
|
||||
}{
|
||||
{"fake mapping", 0, math.MaxUint64, 0, 0x40052d},
|
||||
{"fixed load address", 0x400000, 0x4006fc, 0, 0x40052d},
|
||||
// True user-mode ASLR binaries are ET_DYN rather than ET_EXEC so this case
|
||||
// is a bit artificial except that it approximates the
|
||||
// vmlinux-with-kernel-ASLR case where the binary *is* ET_EXEC.
|
||||
{"simulated ASLR address", 0x500000, 0x5006fc, 0, 0x50052d},
|
||||
} {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
bu := &Binutils{}
|
||||
f, err := bu.Open(filepath.Join("testdata", "exe_linux_64"), tc.start, tc.limit, tc.offset)
|
||||
if err != nil {
|
||||
t.Fatalf("Open: unexpected error %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
syms, err := f.Symbols(regexp.MustCompile("main"), 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Symbols: unexpected error %v", err)
|
||||
}
|
||||
|
||||
m := findSymbol(syms, "main")
|
||||
if m == nil {
|
||||
t.Fatalf("Symbols: did not find main")
|
||||
}
|
||||
for _, addr := range []uint64{m.Start + f.Base(), tc.addr} {
|
||||
gotFrames, err := f.SourceLine(addr)
|
||||
if err != nil {
|
||||
t.Fatalf("SourceLine: unexpected error %v", err)
|
||||
}
|
||||
wantFrames := []plugin.Frame{
|
||||
{Func: "main", File: "/tmp/hello.c", Line: 3},
|
||||
}
|
||||
if !reflect.DeepEqual(gotFrames, wantFrames) {
|
||||
t.Fatalf("SourceLine for main: got %v; want %v\n", gotFrames, wantFrames)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMachoFiles(t *testing.T) {
|
||||
skipUnlessDarwinAmd64(t)
|
||||
|
||||
// Load `file`, pretending it was mapped at `start`. Then get the symbol
|
||||
// table. Check that it contains the symbol `sym` and that the address
|
||||
// `addr` gives the `expected` stack trace.
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
file string
|
||||
start, limit, offset uint64
|
||||
addr uint64
|
||||
sym string
|
||||
expected []plugin.Frame
|
||||
}{
|
||||
{"normal mapping", "exe_mac_64", 0x100000000, math.MaxUint64, 0,
|
||||
0x100000f50, "_main",
|
||||
[]plugin.Frame{
|
||||
{Func: "main", File: "/tmp/hello.c", Line: 3},
|
||||
}},
|
||||
{"other mapping", "exe_mac_64", 0x200000000, math.MaxUint64, 0,
|
||||
0x200000f50, "_main",
|
||||
[]plugin.Frame{
|
||||
{Func: "main", File: "/tmp/hello.c", Line: 3},
|
||||
}},
|
||||
{"lib normal mapping", "lib_mac_64", 0, math.MaxUint64, 0,
|
||||
0xfa0, "_bar",
|
||||
[]plugin.Frame{
|
||||
{Func: "bar", File: "/tmp/lib.c", Line: 5},
|
||||
}},
|
||||
} {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
bu := &Binutils{}
|
||||
f, err := bu.Open(filepath.Join("testdata", tc.file), tc.start, tc.limit, tc.offset)
|
||||
if err != nil {
|
||||
t.Fatalf("Open: unexpected error %v", err)
|
||||
}
|
||||
t.Logf("binutils: %v", bu)
|
||||
if runtime.GOOS == "darwin" && !bu.rep.addr2lineFound && !bu.rep.llvmSymbolizerFound {
|
||||
// On OSX user needs to install gaddr2line or llvm-symbolizer with
|
||||
// Homebrew, skip the test when the environment doesn't have it
|
||||
// installed.
|
||||
t.Skip("couldn't find addr2line or gaddr2line")
|
||||
}
|
||||
defer f.Close()
|
||||
syms, err := f.Symbols(nil, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("Symbols: unexpected error %v", err)
|
||||
}
|
||||
|
||||
m := findSymbol(syms, tc.sym)
|
||||
if m == nil {
|
||||
t.Fatalf("Symbols: could not find symbol %v", tc.sym)
|
||||
}
|
||||
gotFrames, err := f.SourceLine(tc.addr)
|
||||
if err != nil {
|
||||
t.Fatalf("SourceLine: unexpected error %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(gotFrames, tc.expected) {
|
||||
t.Fatalf("SourceLine for main: got %v; want %v\n", gotFrames, tc.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLLVMSymbolizer(t *testing.T) {
|
||||
if runtime.GOOS != "linux" {
|
||||
t.Skip("testtdata/llvm-symbolizer has only been tested on linux")
|
||||
}
|
||||
|
||||
cmd := filepath.Join("testdata", "fake-llvm-symbolizer")
|
||||
symbolizer, err := newLLVMSymbolizer(cmd, "foo", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("newLLVMSymbolizer: unexpected error %v", err)
|
||||
}
|
||||
defer symbolizer.rw.close()
|
||||
|
||||
for _, c := range []struct {
|
||||
addr uint64
|
||||
frames []plugin.Frame
|
||||
}{
|
||||
{0x10, []plugin.Frame{
|
||||
{Func: "Inlined_0x10", File: "foo.h", Line: 0},
|
||||
{Func: "Func_0x10", File: "foo.c", Line: 2},
|
||||
}},
|
||||
{0x20, []plugin.Frame{
|
||||
{Func: "Inlined_0x20", File: "foo.h", Line: 0},
|
||||
{Func: "Func_0x20", File: "foo.c", Line: 2},
|
||||
}},
|
||||
} {
|
||||
frames, err := symbolizer.addrInfo(c.addr)
|
||||
if err != nil {
|
||||
t.Errorf("LLVM: unexpected error %v", err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(frames, c.frames) {
|
||||
t.Errorf("LLVM: expect %v; got %v\n", c.frames, frames)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenMalformedELF(t *testing.T) {
|
||||
// Test that opening a malformed ELF file will report an error containing
|
||||
// the word "ELF".
|
||||
bu := &Binutils{}
|
||||
_, err := bu.Open(filepath.Join("testdata", "malformed_elf"), 0, 0, 0)
|
||||
if err == nil {
|
||||
t.Fatalf("Open: unexpected success")
|
||||
}
|
||||
|
||||
if !strings.Contains(err.Error(), "ELF") {
|
||||
t.Errorf("Open: got %v, want error containing 'ELF'", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenMalformedMachO(t *testing.T) {
|
||||
// Test that opening a malformed Mach-O file will report an error containing
|
||||
// the word "Mach-O".
|
||||
bu := &Binutils{}
|
||||
_, err := bu.Open(filepath.Join("testdata", "malformed_macho"), 0, 0, 0)
|
||||
if err == nil {
|
||||
t.Fatalf("Open: unexpected success")
|
||||
}
|
||||
|
||||
if !strings.Contains(err.Error(), "Mach-O") {
|
||||
t.Errorf("Open: got %v, want error containing 'Mach-O'", err)
|
||||
}
|
||||
}
|
152
src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm_test.go
generated
vendored
152
src/cmd/vendor/github.com/google/pprof/internal/binutils/disasm_test.go
generated
vendored
@ -1,152 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package binutils
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"testing"
|
||||
|
||||
"github.com/google/pprof/internal/plugin"
|
||||
)
|
||||
|
||||
// TestFindSymbols tests the FindSymbols routine using a hardcoded nm output.
|
||||
func TestFindSymbols(t *testing.T) {
|
||||
type testcase struct {
|
||||
query, syms string
|
||||
want []plugin.Sym
|
||||
}
|
||||
|
||||
testsyms := `0000000000001000 t lineA001
|
||||
0000000000001000 t lineA002
|
||||
0000000000001000 t line1000
|
||||
0000000000002000 t line200A
|
||||
0000000000002000 t line2000
|
||||
0000000000002000 t line200B
|
||||
0000000000003000 t line3000
|
||||
0000000000003000 t _ZNK4DumbclEPKc
|
||||
0000000000003000 t lineB00C
|
||||
0000000000003000 t line300D
|
||||
0000000000004000 t _the_end
|
||||
`
|
||||
testcases := []testcase{
|
||||
{
|
||||
"line.*[AC]",
|
||||
testsyms,
|
||||
[]plugin.Sym{
|
||||
{Name: []string{"lineA001"}, File: "object.o", Start: 0x1000, End: 0x1FFF},
|
||||
{Name: []string{"line200A"}, File: "object.o", Start: 0x2000, End: 0x2FFF},
|
||||
{Name: []string{"lineB00C"}, File: "object.o", Start: 0x3000, End: 0x3FFF},
|
||||
},
|
||||
},
|
||||
{
|
||||
"Dumb::operator",
|
||||
testsyms,
|
||||
[]plugin.Sym{
|
||||
{Name: []string{"Dumb::operator()(char const*) const"}, File: "object.o", Start: 0x3000, End: 0x3FFF},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
syms, err := findSymbols([]byte(tc.syms), "object.o", regexp.MustCompile(tc.query), 0)
|
||||
if err != nil {
|
||||
t.Fatalf("%q: findSymbols: %v", tc.query, err)
|
||||
}
|
||||
if err := checkSymbol(syms, tc.want); err != nil {
|
||||
t.Errorf("%q: %v", tc.query, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkSymbol(got []*plugin.Sym, want []plugin.Sym) error {
|
||||
if len(got) != len(want) {
|
||||
return fmt.Errorf("unexpected number of symbols %d (want %d)", len(got), len(want))
|
||||
}
|
||||
|
||||
for i, g := range got {
|
||||
w := want[i]
|
||||
if len(g.Name) != len(w.Name) {
|
||||
return fmt.Errorf("names, got %d, want %d", len(g.Name), len(w.Name))
|
||||
}
|
||||
for n := range g.Name {
|
||||
if g.Name[n] != w.Name[n] {
|
||||
return fmt.Errorf("name %d, got %q, want %q", n, g.Name[n], w.Name[n])
|
||||
}
|
||||
}
|
||||
if g.File != w.File {
|
||||
return fmt.Errorf("filename, got %q, want %q", g.File, w.File)
|
||||
}
|
||||
if g.Start != w.Start {
|
||||
return fmt.Errorf("start address, got %#x, want %#x", g.Start, w.Start)
|
||||
}
|
||||
if g.End != w.End {
|
||||
return fmt.Errorf("end address, got %#x, want %#x", g.End, w.End)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// TestFunctionAssembly tests the FunctionAssembly routine by using a
|
||||
// fake objdump script.
|
||||
func TestFunctionAssembly(t *testing.T) {
|
||||
type testcase struct {
|
||||
s plugin.Sym
|
||||
asm string
|
||||
want []plugin.Inst
|
||||
}
|
||||
testcases := []testcase{
|
||||
{
|
||||
plugin.Sym{Name: []string{"symbol1"}, Start: 0x1000, End: 0x1FFF},
|
||||
` 1000: instruction one
|
||||
1001: instruction two
|
||||
1002: instruction three
|
||||
1003: instruction four
|
||||
`,
|
||||
[]plugin.Inst{
|
||||
{Addr: 0x1000, Text: "instruction one"},
|
||||
{Addr: 0x1001, Text: "instruction two"},
|
||||
{Addr: 0x1002, Text: "instruction three"},
|
||||
{Addr: 0x1003, Text: "instruction four"},
|
||||
},
|
||||
},
|
||||
{
|
||||
plugin.Sym{Name: []string{"symbol2"}, Start: 0x2000, End: 0x2FFF},
|
||||
` 2000: instruction one
|
||||
2001: instruction two
|
||||
`,
|
||||
[]plugin.Inst{
|
||||
{Addr: 0x2000, Text: "instruction one"},
|
||||
{Addr: 0x2001, Text: "instruction two"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
insts, err := disassemble([]byte(tc.asm))
|
||||
if err != nil {
|
||||
t.Fatalf("FunctionAssembly: %v", err)
|
||||
}
|
||||
|
||||
if len(insts) != len(tc.want) {
|
||||
t.Errorf("Unexpected number of assembly instructions %d (want %d)\n", len(insts), len(tc.want))
|
||||
}
|
||||
for i := range insts {
|
||||
if insts[i] != tc.want[i] {
|
||||
t.Errorf("Expected symbol %v, got %v\n", tc.want[i], insts[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
31
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/build_mac.sh
generated
vendored
31
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/build_mac.sh
generated
vendored
@ -1,31 +0,0 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
# This is a script that generates the test MacOS executables in this directory.
|
||||
# It should be needed very rarely to run this script. It is mostly provided
|
||||
# as a future reference on how the original binary set was created.
|
||||
|
||||
set -o errexit
|
||||
|
||||
cat <<EOF >/tmp/hello.cc
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
printf("Hello, world!\n");
|
||||
return 0;
|
||||
}
|
||||
EOF
|
||||
|
||||
cat <<EOF >/tmp/lib.c
|
||||
int foo() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
int bar() {
|
||||
return 2;
|
||||
}
|
||||
EOF
|
||||
|
||||
cd $(dirname $0)
|
||||
rm -rf exe_mac_64* lib_mac_64*
|
||||
clang -g -o exe_mac_64 /tmp/hello.c
|
||||
clang -g -o lib_mac_64 -dynamiclib /tmp/lib.c
|
BIN
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/exe_linux_64
generated
vendored
BIN
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/exe_linux_64
generated
vendored
Binary file not shown.
BIN
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/exe_mac_64
generated
vendored
BIN
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/exe_mac_64
generated
vendored
Binary file not shown.
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.exe_mac_64</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
34
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/fake-llvm-symbolizer
generated
vendored
34
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/fake-llvm-symbolizer
generated
vendored
@ -1,34 +0,0 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Copyright 2014 Google Inc. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Fake llvm-symbolizer to use in tests
|
||||
|
||||
set -f
|
||||
IFS=" "
|
||||
|
||||
while read line; do
|
||||
# line has form:
|
||||
# filename 0xaddr
|
||||
# Emit dummy output that matches llvm-symbolizer output format.
|
||||
set -- $line
|
||||
fname=$1
|
||||
addr=$2
|
||||
echo "Inlined_$addr"
|
||||
echo "$fname.h"
|
||||
echo "Func_$addr"
|
||||
echo "$fname.c:2"
|
||||
echo
|
||||
done
|
BIN
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/lib_mac_64
generated
vendored
BIN
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/lib_mac_64
generated
vendored
Binary file not shown.
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.lib_mac_64</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
Binary file not shown.
1
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/malformed_elf
generated
vendored
1
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/malformed_elf
generated
vendored
@ -1 +0,0 @@
|
||||
ELF˙˙˙˙˙˙˙˙
|
1
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/malformed_macho
generated
vendored
1
src/cmd/vendor/github.com/google/pprof/internal/binutils/testdata/malformed_macho
generated
vendored
@ -1 +0,0 @@
|
||||
销睨<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2
src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go
generated
vendored
2
src/cmd/vendor/github.com/google/pprof/internal/driver/driver_focus.go
generated
vendored
@ -25,7 +25,7 @@ import (
|
||||
"github.com/google/pprof/profile"
|
||||
)
|
||||
|
||||
var tagFilterRangeRx = regexp.MustCompile("([[:digit:]]+)([[:alpha:]]+)")
|
||||
var tagFilterRangeRx = regexp.MustCompile("([+-]?[[:digit:]]+)([[:alpha:]]+)")
|
||||
|
||||
// applyFocus filters samples based on the focus/ignore options
|
||||
func applyFocus(prof *profile.Profile, numLabelUnits map[string]string, v variables, ui plugin.UI) error {
|
||||
|
1606
src/cmd/vendor/github.com/google/pprof/internal/driver/driver_test.go
generated
vendored
1606
src/cmd/vendor/github.com/google/pprof/internal/driver/driver_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
758
src/cmd/vendor/github.com/google/pprof/internal/driver/fetch_test.go
generated
vendored
758
src/cmd/vendor/github.com/google/pprof/internal/driver/fetch_test.go
generated
vendored
@ -1,758 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package driver
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/pprof/internal/binutils"
|
||||
"github.com/google/pprof/internal/plugin"
|
||||
"github.com/google/pprof/internal/proftest"
|
||||
"github.com/google/pprof/internal/symbolizer"
|
||||
"github.com/google/pprof/internal/transport"
|
||||
"github.com/google/pprof/profile"
|
||||
)
|
||||
|
||||
func TestSymbolizationPath(t *testing.T) {
|
||||
if runtime.GOOS == "windows" {
|
||||
t.Skip("test assumes Unix paths")
|
||||
}
|
||||
|
||||
// Save environment variables to restore after test
|
||||
saveHome := os.Getenv(homeEnv())
|
||||
savePath := os.Getenv("PPROF_BINARY_PATH")
|
||||
|
||||
tempdir, err := ioutil.TempDir("", "home")
|
||||
if err != nil {
|
||||
t.Fatal("creating temp dir: ", err)
|
||||
}
|
||||
defer os.RemoveAll(tempdir)
|
||||
os.MkdirAll(filepath.Join(tempdir, "pprof", "binaries", "abcde10001"), 0700)
|
||||
os.Create(filepath.Join(tempdir, "pprof", "binaries", "abcde10001", "binary"))
|
||||
|
||||
obj := testObj{tempdir}
|
||||
os.Setenv(homeEnv(), tempdir)
|
||||
for _, tc := range []struct {
|
||||
env, file, buildID, want string
|
||||
msgCount int
|
||||
}{
|
||||
{"", "/usr/bin/binary", "", "/usr/bin/binary", 0},
|
||||
{"", "/usr/bin/binary", "fedcb10000", "/usr/bin/binary", 0},
|
||||
{"/usr", "/bin/binary", "", "/usr/bin/binary", 0},
|
||||
{"", "/prod/path/binary", "abcde10001", filepath.Join(tempdir, "pprof/binaries/abcde10001/binary"), 0},
|
||||
{"/alternate/architecture", "/usr/bin/binary", "", "/alternate/architecture/binary", 0},
|
||||
{"/alternate/architecture", "/usr/bin/binary", "abcde10001", "/alternate/architecture/binary", 0},
|
||||
{"/nowhere:/alternate/architecture", "/usr/bin/binary", "fedcb10000", "/usr/bin/binary", 1},
|
||||
{"/nowhere:/alternate/architecture", "/usr/bin/binary", "abcde10002", "/usr/bin/binary", 1},
|
||||
} {
|
||||
os.Setenv("PPROF_BINARY_PATH", tc.env)
|
||||
p := &profile.Profile{
|
||||
Mapping: []*profile.Mapping{
|
||||
{
|
||||
File: tc.file,
|
||||
BuildID: tc.buildID,
|
||||
},
|
||||
},
|
||||
}
|
||||
s := &source{}
|
||||
locateBinaries(p, s, obj, &proftest.TestUI{T: t, Ignore: tc.msgCount})
|
||||
if file := p.Mapping[0].File; file != tc.want {
|
||||
t.Errorf("%s:%s:%s, want %s, got %s", tc.env, tc.file, tc.buildID, tc.want, file)
|
||||
}
|
||||
}
|
||||
os.Setenv(homeEnv(), saveHome)
|
||||
os.Setenv("PPROF_BINARY_PATH", savePath)
|
||||
}
|
||||
|
||||
func TestCollectMappingSources(t *testing.T) {
|
||||
const startAddress uint64 = 0x40000
|
||||
const url = "http://example.com"
|
||||
for _, tc := range []struct {
|
||||
file, buildID string
|
||||
want plugin.MappingSources
|
||||
}{
|
||||
{"/usr/bin/binary", "buildId", mappingSources("buildId", url, startAddress)},
|
||||
{"/usr/bin/binary", "", mappingSources("/usr/bin/binary", url, startAddress)},
|
||||
{"", "", mappingSources(url, url, startAddress)},
|
||||
} {
|
||||
p := &profile.Profile{
|
||||
Mapping: []*profile.Mapping{
|
||||
{
|
||||
File: tc.file,
|
||||
BuildID: tc.buildID,
|
||||
Start: startAddress,
|
||||
},
|
||||
},
|
||||
}
|
||||
got := collectMappingSources(p, url)
|
||||
if !reflect.DeepEqual(got, tc.want) {
|
||||
t.Errorf("%s:%s, want %v, got %v", tc.file, tc.buildID, tc.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnsourceMappings(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
file, buildID, want string
|
||||
}{
|
||||
{"/usr/bin/binary", "buildId", "/usr/bin/binary"},
|
||||
{"http://example.com", "", ""},
|
||||
} {
|
||||
p := &profile.Profile{
|
||||
Mapping: []*profile.Mapping{
|
||||
{
|
||||
File: tc.file,
|
||||
BuildID: tc.buildID,
|
||||
},
|
||||
},
|
||||
}
|
||||
unsourceMappings(p)
|
||||
if got := p.Mapping[0].File; got != tc.want {
|
||||
t.Errorf("%s:%s, want %s, got %s", tc.file, tc.buildID, tc.want, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type testObj struct {
|
||||
home string
|
||||
}
|
||||
|
||||
func (o testObj) Open(file string, start, limit, offset uint64) (plugin.ObjFile, error) {
|
||||
switch file {
|
||||
case "/alternate/architecture/binary":
|
||||
return testFile{file, "abcde10001"}, nil
|
||||
case "/usr/bin/binary":
|
||||
return testFile{file, "fedcb10000"}, nil
|
||||
case filepath.Join(o.home, "pprof/binaries/abcde10001/binary"):
|
||||
return testFile{file, "abcde10001"}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("not found: %s", file)
|
||||
}
|
||||
func (testObj) Demangler(_ string) func(names []string) (map[string]string, error) {
|
||||
return func(names []string) (map[string]string, error) { return nil, nil }
|
||||
}
|
||||
func (testObj) Disasm(file string, start, end uint64) ([]plugin.Inst, error) { return nil, nil }
|
||||
|
||||
type testFile struct{ name, buildID string }
|
||||
|
||||
func (f testFile) Name() string { return f.name }
|
||||
func (testFile) Base() uint64 { return 0 }
|
||||
func (f testFile) BuildID() string { return f.buildID }
|
||||
func (testFile) SourceLine(addr uint64) ([]plugin.Frame, error) { return nil, nil }
|
||||
func (testFile) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) { return nil, nil }
|
||||
func (testFile) Close() error { return nil }
|
||||
|
||||
func TestFetch(t *testing.T) {
|
||||
const path = "testdata/"
|
||||
type testcase struct {
|
||||
source, execName string
|
||||
}
|
||||
|
||||
for _, tc := range []testcase{
|
||||
{path + "go.crc32.cpu", ""},
|
||||
{path + "go.nomappings.crash", "/bin/gotest.exe"},
|
||||
{"http://localhost/profile?file=cppbench.cpu", ""},
|
||||
} {
|
||||
p, _, _, err := grabProfile(&source{ExecName: tc.execName}, tc.source, nil, testObj{}, &proftest.TestUI{T: t}, &httpTransport{})
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %s", tc.source, err)
|
||||
}
|
||||
if len(p.Sample) == 0 {
|
||||
t.Errorf("%s: want non-zero samples", tc.source)
|
||||
}
|
||||
if e := tc.execName; e != "" {
|
||||
switch {
|
||||
case len(p.Mapping) == 0 || p.Mapping[0] == nil:
|
||||
t.Errorf("%s: want mapping[0].execName == %s, got no mappings", tc.source, e)
|
||||
case p.Mapping[0].File != e:
|
||||
t.Errorf("%s: want mapping[0].execName == %s, got %s", tc.source, e, p.Mapping[0].File)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFetchWithBase(t *testing.T) {
|
||||
baseVars := pprofVariables
|
||||
defer func() { pprofVariables = baseVars }()
|
||||
|
||||
type WantSample struct {
|
||||
values []int64
|
||||
labels map[string][]string
|
||||
}
|
||||
|
||||
const path = "testdata/"
|
||||
type testcase struct {
|
||||
desc string
|
||||
sources []string
|
||||
bases []string
|
||||
diffBases []string
|
||||
normalize bool
|
||||
wantSamples []WantSample
|
||||
wantErrorMsg string
|
||||
}
|
||||
|
||||
testcases := []testcase{
|
||||
{
|
||||
"not normalized base is same as source",
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.contention"},
|
||||
nil,
|
||||
false,
|
||||
nil,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"not normalized base is same as source",
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.contention"},
|
||||
nil,
|
||||
false,
|
||||
nil,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"not normalized single source, multiple base (all profiles same)",
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.contention", path + "cppbench.contention"},
|
||||
nil,
|
||||
false,
|
||||
[]WantSample{
|
||||
{
|
||||
values: []int64{-2700, -608881724},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{-100, -23992},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{-200, -179943},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{-100, -17778444},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{-100, -75976},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{-300, -63568134},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"",
|
||||
},
|
||||
{
|
||||
"not normalized, different base and source",
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.small.contention"},
|
||||
nil,
|
||||
false,
|
||||
[]WantSample{
|
||||
{
|
||||
values: []int64{1700, 608878600},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{100, 23992},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{200, 179943},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{100, 17778444},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{100, 75976},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{300, 63568134},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"",
|
||||
},
|
||||
{
|
||||
"normalized base is same as source",
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.contention"},
|
||||
nil,
|
||||
true,
|
||||
nil,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"normalized single source, multiple base (all profiles same)",
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.contention", path + "cppbench.contention"},
|
||||
nil,
|
||||
true,
|
||||
nil,
|
||||
"",
|
||||
},
|
||||
{
|
||||
"normalized different base and source",
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.small.contention"},
|
||||
nil,
|
||||
true,
|
||||
[]WantSample{
|
||||
{
|
||||
values: []int64{-229, -370},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{28, 0},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{57, 0},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{28, 80},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{28, 0},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{85, 287},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
},
|
||||
"",
|
||||
},
|
||||
{
|
||||
"not normalized diff base is same as source",
|
||||
[]string{path + "cppbench.contention"},
|
||||
nil,
|
||||
[]string{path + "cppbench.contention"},
|
||||
false,
|
||||
[]WantSample{
|
||||
{
|
||||
values: []int64{2700, 608881724},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{100, 23992},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{200, 179943},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{100, 17778444},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{100, 75976},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{300, 63568134},
|
||||
labels: map[string][]string{},
|
||||
},
|
||||
{
|
||||
values: []int64{-2700, -608881724},
|
||||
labels: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
{
|
||||
values: []int64{-100, -23992},
|
||||
labels: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
{
|
||||
values: []int64{-200, -179943},
|
||||
labels: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
{
|
||||
values: []int64{-100, -17778444},
|
||||
labels: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
{
|
||||
values: []int64{-100, -75976},
|
||||
labels: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
{
|
||||
values: []int64{-300, -63568134},
|
||||
labels: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
},
|
||||
"",
|
||||
},
|
||||
{
|
||||
"diff_base and base both specified",
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.contention"},
|
||||
[]string{path + "cppbench.contention"},
|
||||
false,
|
||||
nil,
|
||||
"-base and -diff_base flags cannot both be specified",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
pprofVariables = baseVars.makeCopy()
|
||||
f := testFlags{
|
||||
stringLists: map[string][]string{
|
||||
"base": tc.bases,
|
||||
"diff_base": tc.diffBases,
|
||||
},
|
||||
bools: map[string]bool{
|
||||
"normalize": tc.normalize,
|
||||
},
|
||||
}
|
||||
f.args = tc.sources
|
||||
|
||||
o := setDefaults(&plugin.Options{
|
||||
UI: &proftest.TestUI{T: t, AllowRx: "Local symbolization failed|Some binary filenames not available"},
|
||||
Flagset: f,
|
||||
HTTPTransport: transport.New(nil),
|
||||
})
|
||||
src, _, err := parseFlags(o)
|
||||
|
||||
if tc.wantErrorMsg != "" {
|
||||
if err == nil {
|
||||
t.Fatalf("got nil, want error %q", tc.wantErrorMsg)
|
||||
}
|
||||
|
||||
if gotErrMsg := err.Error(); gotErrMsg != tc.wantErrorMsg {
|
||||
t.Fatalf("got error %q, want error %q", gotErrMsg, tc.wantErrorMsg)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("got error %q, want no error", err)
|
||||
}
|
||||
|
||||
p, err := fetchProfiles(src, o)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("got error %q, want no error", err)
|
||||
}
|
||||
|
||||
if got, want := len(p.Sample), len(tc.wantSamples); got != want {
|
||||
t.Fatalf("got %d samples want %d", got, want)
|
||||
}
|
||||
|
||||
for i, sample := range p.Sample {
|
||||
if !reflect.DeepEqual(tc.wantSamples[i].values, sample.Value) {
|
||||
t.Errorf("for sample %d got values %v, want %v", i, sample.Value, tc.wantSamples[i])
|
||||
}
|
||||
if !reflect.DeepEqual(tc.wantSamples[i].labels, sample.Label) {
|
||||
t.Errorf("for sample %d got labels %v, want %v", i, sample.Label, tc.wantSamples[i].labels)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// mappingSources creates MappingSources map with a single item.
|
||||
func mappingSources(key, source string, start uint64) plugin.MappingSources {
|
||||
return plugin.MappingSources{
|
||||
key: []struct {
|
||||
Source string
|
||||
Start uint64
|
||||
}{
|
||||
{Source: source, Start: start},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type httpTransport struct{}
|
||||
|
||||
func (tr *httpTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
values := req.URL.Query()
|
||||
file := values.Get("file")
|
||||
|
||||
if file == "" {
|
||||
return nil, fmt.Errorf("want .../file?profile, got %s", req.URL.String())
|
||||
}
|
||||
|
||||
t := &http.Transport{}
|
||||
t.RegisterProtocol("file", http.NewFileTransport(http.Dir("testdata/")))
|
||||
|
||||
c := &http.Client{Transport: t}
|
||||
return c.Get("file:///" + file)
|
||||
}
|
||||
|
||||
func closedError() string {
|
||||
if runtime.GOOS == "plan9" {
|
||||
return "listen hungup"
|
||||
}
|
||||
return "use of closed"
|
||||
}
|
||||
|
||||
func TestHTTPSInsecure(t *testing.T) {
|
||||
if runtime.GOOS == "nacl" || runtime.GOOS == "js" {
|
||||
t.Skip("test assumes tcp available")
|
||||
}
|
||||
saveHome := os.Getenv(homeEnv())
|
||||
tempdir, err := ioutil.TempDir("", "home")
|
||||
if err != nil {
|
||||
t.Fatal("creating temp dir: ", err)
|
||||
}
|
||||
defer os.RemoveAll(tempdir)
|
||||
|
||||
// pprof writes to $HOME/pprof by default which is not necessarily
|
||||
// writeable (e.g. on a Debian buildd) so set $HOME to something we
|
||||
// know we can write to for the duration of the test.
|
||||
os.Setenv(homeEnv(), tempdir)
|
||||
defer os.Setenv(homeEnv(), saveHome)
|
||||
|
||||
baseVars := pprofVariables
|
||||
pprofVariables = baseVars.makeCopy()
|
||||
defer func() { pprofVariables = baseVars }()
|
||||
|
||||
tlsCert, _, _ := selfSignedCert(t, "")
|
||||
tlsConfig := &tls.Config{Certificates: []tls.Certificate{tlsCert}}
|
||||
|
||||
l, err := tls.Listen("tcp", "localhost:0", tlsConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("net.Listen: got error %v, want no error", err)
|
||||
}
|
||||
|
||||
donec := make(chan error, 1)
|
||||
go func(donec chan<- error) {
|
||||
donec <- http.Serve(l, nil)
|
||||
}(donec)
|
||||
defer func() {
|
||||
if got, want := <-donec, closedError(); !strings.Contains(got.Error(), want) {
|
||||
t.Fatalf("Serve got error %v, want %q", got, want)
|
||||
}
|
||||
}()
|
||||
defer l.Close()
|
||||
|
||||
outputTempFile, err := ioutil.TempFile("", "profile_output")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create tempfile: %v", err)
|
||||
}
|
||||
defer os.Remove(outputTempFile.Name())
|
||||
defer outputTempFile.Close()
|
||||
|
||||
address := "https+insecure://" + l.Addr().String() + "/debug/pprof/goroutine"
|
||||
s := &source{
|
||||
Sources: []string{address},
|
||||
Seconds: 10,
|
||||
Timeout: 10,
|
||||
Symbolize: "remote",
|
||||
}
|
||||
o := &plugin.Options{
|
||||
Obj: &binutils.Binutils{},
|
||||
UI: &proftest.TestUI{T: t, AllowRx: "Saved profile in"},
|
||||
HTTPTransport: transport.New(nil),
|
||||
}
|
||||
o.Sym = &symbolizer.Symbolizer{Obj: o.Obj, UI: o.UI}
|
||||
p, err := fetchProfiles(s, o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(p.SampleType) == 0 {
|
||||
t.Fatalf("fetchProfiles(%s) got empty profile: len(p.SampleType)==0", address)
|
||||
}
|
||||
if len(p.Function) == 0 {
|
||||
t.Fatalf("fetchProfiles(%s) got non-symbolized profile: len(p.Function)==0", address)
|
||||
}
|
||||
if err := checkProfileHasFunction(p, "TestHTTPSInsecure"); err != nil {
|
||||
t.Fatalf("fetchProfiles(%s) %v", address, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHTTPSWithServerCertFetch(t *testing.T) {
|
||||
if runtime.GOOS == "nacl" || runtime.GOOS == "js" {
|
||||
t.Skip("test assumes tcp available")
|
||||
}
|
||||
saveHome := os.Getenv(homeEnv())
|
||||
tempdir, err := ioutil.TempDir("", "home")
|
||||
if err != nil {
|
||||
t.Fatal("creating temp dir: ", err)
|
||||
}
|
||||
defer os.RemoveAll(tempdir)
|
||||
|
||||
// pprof writes to $HOME/pprof by default which is not necessarily
|
||||
// writeable (e.g. on a Debian buildd) so set $HOME to something we
|
||||
// know we can write to for the duration of the test.
|
||||
os.Setenv(homeEnv(), tempdir)
|
||||
defer os.Setenv(homeEnv(), saveHome)
|
||||
|
||||
baseVars := pprofVariables
|
||||
pprofVariables = baseVars.makeCopy()
|
||||
defer func() { pprofVariables = baseVars }()
|
||||
|
||||
cert, certBytes, keyBytes := selfSignedCert(t, "localhost")
|
||||
cas := x509.NewCertPool()
|
||||
cas.AppendCertsFromPEM(certBytes)
|
||||
|
||||
tlsConfig := &tls.Config{
|
||||
RootCAs: cas,
|
||||
Certificates: []tls.Certificate{cert},
|
||||
ClientAuth: tls.RequireAndVerifyClientCert,
|
||||
ClientCAs: cas,
|
||||
}
|
||||
|
||||
l, err := tls.Listen("tcp", "localhost:0", tlsConfig)
|
||||
if err != nil {
|
||||
t.Fatalf("net.Listen: got error %v, want no error", err)
|
||||
}
|
||||
|
||||
donec := make(chan error, 1)
|
||||
go func(donec chan<- error) {
|
||||
donec <- http.Serve(l, nil)
|
||||
}(donec)
|
||||
defer func() {
|
||||
if got, want := <-donec, closedError(); !strings.Contains(got.Error(), want) {
|
||||
t.Fatalf("Serve got error %v, want %q", got, want)
|
||||
}
|
||||
}()
|
||||
defer l.Close()
|
||||
|
||||
outputTempFile, err := ioutil.TempFile("", "profile_output")
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create tempfile: %v", err)
|
||||
}
|
||||
defer os.Remove(outputTempFile.Name())
|
||||
defer outputTempFile.Close()
|
||||
|
||||
// Get port from the address, so request to the server can be made using
|
||||
// the host name specified in certificates.
|
||||
_, portStr, err := net.SplitHostPort(l.Addr().String())
|
||||
if err != nil {
|
||||
t.Fatalf("cannot get port from URL: %v", err)
|
||||
}
|
||||
address := "https://" + "localhost:" + portStr + "/debug/pprof/goroutine"
|
||||
s := &source{
|
||||
Sources: []string{address},
|
||||
Seconds: 10,
|
||||
Timeout: 10,
|
||||
Symbolize: "remote",
|
||||
}
|
||||
|
||||
certTempFile, err := ioutil.TempFile("", "cert_output")
|
||||
if err != nil {
|
||||
t.Errorf("cannot create cert tempfile: %v", err)
|
||||
}
|
||||
defer os.Remove(certTempFile.Name())
|
||||
defer certTempFile.Close()
|
||||
certTempFile.Write(certBytes)
|
||||
|
||||
keyTempFile, err := ioutil.TempFile("", "key_output")
|
||||
if err != nil {
|
||||
t.Errorf("cannot create key tempfile: %v", err)
|
||||
}
|
||||
defer os.Remove(keyTempFile.Name())
|
||||
defer keyTempFile.Close()
|
||||
keyTempFile.Write(keyBytes)
|
||||
|
||||
f := &testFlags{
|
||||
strings: map[string]string{
|
||||
"tls_cert": certTempFile.Name(),
|
||||
"tls_key": keyTempFile.Name(),
|
||||
"tls_ca": certTempFile.Name(),
|
||||
},
|
||||
}
|
||||
o := &plugin.Options{
|
||||
Obj: &binutils.Binutils{},
|
||||
UI: &proftest.TestUI{T: t, AllowRx: "Saved profile in"},
|
||||
Flagset: f,
|
||||
HTTPTransport: transport.New(f),
|
||||
}
|
||||
|
||||
o.Sym = &symbolizer.Symbolizer{Obj: o.Obj, UI: o.UI, Transport: o.HTTPTransport}
|
||||
p, err := fetchProfiles(s, o)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(p.SampleType) == 0 {
|
||||
t.Fatalf("fetchProfiles(%s) got empty profile: len(p.SampleType)==0", address)
|
||||
}
|
||||
if len(p.Function) == 0 {
|
||||
t.Fatalf("fetchProfiles(%s) got non-symbolized profile: len(p.Function)==0", address)
|
||||
}
|
||||
if err := checkProfileHasFunction(p, "TestHTTPSWithServerCertFetch"); err != nil {
|
||||
t.Fatalf("fetchProfiles(%s) %v", address, err)
|
||||
}
|
||||
}
|
||||
|
||||
func checkProfileHasFunction(p *profile.Profile, fname string) error {
|
||||
for _, f := range p.Function {
|
||||
if strings.Contains(f.Name, fname) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("got %s, want function %q", p.String(), fname)
|
||||
}
|
||||
|
||||
// selfSignedCert generates a self-signed certificate, and returns the
|
||||
// generated certificate, and byte arrays containing the certificate and
|
||||
// key associated with the certificate.
|
||||
func selfSignedCert(t *testing.T, host string) (tls.Certificate, []byte, []byte) {
|
||||
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to generate private key: %v", err)
|
||||
}
|
||||
b, err := x509.MarshalECPrivateKey(privKey)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal private key: %v", err)
|
||||
}
|
||||
bk := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
|
||||
|
||||
tmpl := x509.Certificate{
|
||||
SerialNumber: big.NewInt(1),
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(10 * time.Minute),
|
||||
IsCA: true,
|
||||
DNSNames: []string{host},
|
||||
}
|
||||
|
||||
b, err = x509.CreateCertificate(rand.Reader, &tmpl, &tmpl, privKey.Public(), privKey)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create cert: %v", err)
|
||||
}
|
||||
bc := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: b})
|
||||
|
||||
cert, err := tls.X509KeyPair(bc, bk)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create TLS key pair: %v", err)
|
||||
}
|
||||
return cert, bc, bk
|
||||
}
|
14
src/cmd/vendor/github.com/google/pprof/internal/driver/flags.go
generated
vendored
14
src/cmd/vendor/github.com/google/pprof/internal/driver/flags.go
generated
vendored
@ -1,3 +1,17 @@
|
||||
// Copyright 2018 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package driver
|
||||
|
||||
import (
|
||||
|
316
src/cmd/vendor/github.com/google/pprof/internal/driver/interactive_test.go
generated
vendored
316
src/cmd/vendor/github.com/google/pprof/internal/driver/interactive_test.go
generated
vendored
@ -1,316 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package driver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/pprof/internal/plugin"
|
||||
"github.com/google/pprof/internal/proftest"
|
||||
"github.com/google/pprof/internal/report"
|
||||
"github.com/google/pprof/internal/transport"
|
||||
"github.com/google/pprof/profile"
|
||||
)
|
||||
|
||||
func TestShell(t *testing.T) {
|
||||
p := &profile.Profile{}
|
||||
generateReportWrapper = checkValue
|
||||
defer func() { generateReportWrapper = generateReport }()
|
||||
|
||||
// Use test commands and variables to exercise interactive processing
|
||||
var savedCommands commands
|
||||
savedCommands, pprofCommands = pprofCommands, testCommands
|
||||
defer func() { pprofCommands = savedCommands }()
|
||||
|
||||
savedVariables := pprofVariables
|
||||
defer func() { pprofVariables = savedVariables }()
|
||||
|
||||
// Random interleave of independent scripts
|
||||
pprofVariables = testVariables(savedVariables)
|
||||
|
||||
// pass in HTTPTransport when setting defaults, because otherwise default
|
||||
// transport will try to add flags to the default flag set.
|
||||
o := setDefaults(&plugin.Options{HTTPTransport: transport.New(nil)})
|
||||
o.UI = newUI(t, interleave(script, 0))
|
||||
if err := interactive(p, o); err != nil {
|
||||
t.Error("first attempt:", err)
|
||||
}
|
||||
// Random interleave of independent scripts
|
||||
pprofVariables = testVariables(savedVariables)
|
||||
o.UI = newUI(t, interleave(script, 1))
|
||||
if err := interactive(p, o); err != nil {
|
||||
t.Error("second attempt:", err)
|
||||
}
|
||||
|
||||
// Random interleave of independent scripts with shortcuts
|
||||
pprofVariables = testVariables(savedVariables)
|
||||
var scScript []string
|
||||
pprofShortcuts, scScript = makeShortcuts(interleave(script, 2), 1)
|
||||
o.UI = newUI(t, scScript)
|
||||
if err := interactive(p, o); err != nil {
|
||||
t.Error("first shortcut attempt:", err)
|
||||
}
|
||||
|
||||
// Random interleave of independent scripts with shortcuts
|
||||
pprofVariables = testVariables(savedVariables)
|
||||
pprofShortcuts, scScript = makeShortcuts(interleave(script, 1), 2)
|
||||
o.UI = newUI(t, scScript)
|
||||
if err := interactive(p, o); err != nil {
|
||||
t.Error("second shortcut attempt:", err)
|
||||
}
|
||||
|
||||
// Group with invalid value
|
||||
pprofVariables = testVariables(savedVariables)
|
||||
ui := &proftest.TestUI{
|
||||
T: t,
|
||||
Input: []string{"cumulative=this"},
|
||||
AllowRx: `Unrecognized value for cumulative: "this". Use one of cum, flat`,
|
||||
}
|
||||
o.UI = ui
|
||||
if err := interactive(p, o); err != nil {
|
||||
t.Error("invalid group value:", err)
|
||||
}
|
||||
// Confirm error message written out once.
|
||||
if ui.NumAllowRxMatches != 1 {
|
||||
t.Errorf("want error message to be printed 1 time, got %v", ui.NumAllowRxMatches)
|
||||
}
|
||||
// Verify propagation of IO errors
|
||||
pprofVariables = testVariables(savedVariables)
|
||||
o.UI = newUI(t, []string{"**error**"})
|
||||
if err := interactive(p, o); err == nil {
|
||||
t.Error("expected IO error, got nil")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var testCommands = commands{
|
||||
"check": &command{report.Raw, nil, nil, true, "", ""},
|
||||
}
|
||||
|
||||
func testVariables(base variables) variables {
|
||||
v := base.makeCopy()
|
||||
|
||||
v["b"] = &variable{boolKind, "f", "", ""}
|
||||
v["bb"] = &variable{boolKind, "f", "", ""}
|
||||
v["i"] = &variable{intKind, "0", "", ""}
|
||||
v["ii"] = &variable{intKind, "0", "", ""}
|
||||
v["f"] = &variable{floatKind, "0", "", ""}
|
||||
v["ff"] = &variable{floatKind, "0", "", ""}
|
||||
v["s"] = &variable{stringKind, "", "", ""}
|
||||
v["ss"] = &variable{stringKind, "", "", ""}
|
||||
|
||||
v["ta"] = &variable{boolKind, "f", "radio", ""}
|
||||
v["tb"] = &variable{boolKind, "f", "radio", ""}
|
||||
v["tc"] = &variable{boolKind, "t", "radio", ""}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// script contains sequences of commands to be executed for testing. Commands
|
||||
// are split by semicolon and interleaved randomly, so they must be
|
||||
// independent from each other.
|
||||
var script = []string{
|
||||
"bb=true;bb=false;check bb=false;bb=yes;check bb=true",
|
||||
"b=1;check b=true;b=n;check b=false",
|
||||
"i=-1;i=-2;check i=-2;i=999999;check i=999999",
|
||||
"check ii=0;ii=-1;check ii=-1;ii=100;check ii=100",
|
||||
"f=-1;f=-2.5;check f=-2.5;f=0.0001;check f=0.0001",
|
||||
"check ff=0;ff=-1.01;check ff=-1.01;ff=100;check ff=100",
|
||||
"s=one;s=two;check s=two",
|
||||
"ss=tree;check ss=tree;ss=;check ss;ss=forest;check ss=forest",
|
||||
"ta=true;check ta=true;check tb=false;check tc=false;tb=1;check tb=true;check ta=false;check tc=false;tc=yes;check tb=false;check ta=false;check tc=true",
|
||||
}
|
||||
|
||||
func makeShortcuts(input []string, seed int) (shortcuts, []string) {
|
||||
rand.Seed(int64(seed))
|
||||
|
||||
s := shortcuts{}
|
||||
var output, chunk []string
|
||||
for _, l := range input {
|
||||
chunk = append(chunk, l)
|
||||
switch rand.Intn(3) {
|
||||
case 0:
|
||||
// Create a macro for commands in 'chunk'.
|
||||
macro := fmt.Sprintf("alias%d", len(s))
|
||||
s[macro] = chunk
|
||||
output = append(output, macro)
|
||||
chunk = nil
|
||||
case 1:
|
||||
// Append commands in 'chunk' by themselves.
|
||||
output = append(output, chunk...)
|
||||
chunk = nil
|
||||
case 2:
|
||||
// Accumulate commands into 'chunk'
|
||||
}
|
||||
}
|
||||
output = append(output, chunk...)
|
||||
return s, output
|
||||
}
|
||||
|
||||
func newUI(t *testing.T, input []string) plugin.UI {
|
||||
return &proftest.TestUI{
|
||||
T: t,
|
||||
Input: input,
|
||||
}
|
||||
}
|
||||
|
||||
func checkValue(p *profile.Profile, cmd []string, vars variables, o *plugin.Options) error {
|
||||
if len(cmd) != 2 {
|
||||
return fmt.Errorf("expected len(cmd)==2, got %v", cmd)
|
||||
}
|
||||
|
||||
input := cmd[1]
|
||||
args := strings.SplitN(input, "=", 2)
|
||||
if len(args) == 0 {
|
||||
return fmt.Errorf("unexpected empty input")
|
||||
}
|
||||
name, value := args[0], ""
|
||||
if len(args) == 2 {
|
||||
value = args[1]
|
||||
}
|
||||
|
||||
gotv := vars[name]
|
||||
if gotv == nil {
|
||||
return fmt.Errorf("Could not find variable named %s", name)
|
||||
}
|
||||
|
||||
if got := gotv.stringValue(); got != value {
|
||||
return fmt.Errorf("Variable %s, want %s, got %s", name, value, got)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func interleave(input []string, seed int) []string {
|
||||
var inputs [][]string
|
||||
for _, s := range input {
|
||||
inputs = append(inputs, strings.Split(s, ";"))
|
||||
}
|
||||
rand.Seed(int64(seed))
|
||||
var output []string
|
||||
for len(inputs) > 0 {
|
||||
next := rand.Intn(len(inputs))
|
||||
output = append(output, inputs[next][0])
|
||||
if tail := inputs[next][1:]; len(tail) > 0 {
|
||||
inputs[next] = tail
|
||||
} else {
|
||||
inputs = append(inputs[:next], inputs[next+1:]...)
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func TestInteractiveCommands(t *testing.T) {
|
||||
type interactiveTestcase struct {
|
||||
input string
|
||||
want map[string]string
|
||||
}
|
||||
|
||||
testcases := []interactiveTestcase{
|
||||
{
|
||||
"top 10 --cum focus1 -ignore focus2",
|
||||
map[string]string{
|
||||
"functions": "true",
|
||||
"nodecount": "10",
|
||||
"cum": "true",
|
||||
"focus": "focus1|focus2",
|
||||
"ignore": "ignore",
|
||||
},
|
||||
},
|
||||
{
|
||||
"top10 --cum focus1 -ignore focus2",
|
||||
map[string]string{
|
||||
"functions": "true",
|
||||
"nodecount": "10",
|
||||
"cum": "true",
|
||||
"focus": "focus1|focus2",
|
||||
"ignore": "ignore",
|
||||
},
|
||||
},
|
||||
{
|
||||
"dot",
|
||||
map[string]string{
|
||||
"functions": "true",
|
||||
"nodecount": "80",
|
||||
"cum": "false",
|
||||
},
|
||||
},
|
||||
{
|
||||
"tags -ignore1 -ignore2 focus1 >out",
|
||||
map[string]string{
|
||||
"functions": "true",
|
||||
"nodecount": "80",
|
||||
"cum": "false",
|
||||
"output": "out",
|
||||
"tagfocus": "focus1",
|
||||
"tagignore": "ignore1|ignore2",
|
||||
},
|
||||
},
|
||||
{
|
||||
"weblist find -test",
|
||||
map[string]string{
|
||||
"functions": "false",
|
||||
"addresses": "true",
|
||||
"noinlines": "true",
|
||||
"nodecount": "0",
|
||||
"cum": "false",
|
||||
"flat": "true",
|
||||
"ignore": "test",
|
||||
},
|
||||
},
|
||||
{
|
||||
"callgrind fun -ignore >out",
|
||||
map[string]string{
|
||||
"functions": "false",
|
||||
"addresses": "true",
|
||||
"nodecount": "0",
|
||||
"cum": "false",
|
||||
"flat": "true",
|
||||
"output": "out",
|
||||
},
|
||||
},
|
||||
{
|
||||
"999",
|
||||
nil, // Error
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
cmd, vars, err := parseCommandLine(strings.Fields(tc.input))
|
||||
if tc.want == nil && err != nil {
|
||||
// Error expected
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("failed on %q: %v", tc.input, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// Get report output format
|
||||
c := pprofCommands[cmd[0]]
|
||||
if c == nil {
|
||||
t.Errorf("unexpected nil command")
|
||||
}
|
||||
vars = applyCommandOverrides(cmd[0], c.format, vars)
|
||||
|
||||
for n, want := range tc.want {
|
||||
if got := vars[n].stringValue(); got != want {
|
||||
t.Errorf("failed on %q, cmd=%q, %s got %s, want %s", tc.input, cmd, n, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
24
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.contention
generated
vendored
24
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.contention
generated
vendored
@ -1,24 +0,0 @@
|
||||
--- contentionz 1 ---
|
||||
cycles/second = 3201000000
|
||||
sampling period = 100
|
||||
ms since reset = 16502830
|
||||
discarded samples = 0
|
||||
19490304 27 @ 0xbccc97 0xc61202 0x42ed5f 0x42edc1 0x42e15a 0x5261af 0x526edf 0x5280ab 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
|
||||
768 1 @ 0xbccc97 0xa42dc7 0xa456e4 0x7fcdc2ff214e
|
||||
5760 2 @ 0xbccc97 0xb82b73 0xb82bcb 0xb87eab 0xb8814c 0x4e969d 0x4faa17 0x4fc5f6 0x4fd028 0x4fd230 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
|
||||
569088 1 @ 0xbccc97 0xb82b73 0xb82bcb 0xb87f08 0xb8814c 0x42ed5f 0x42edc1 0x42e15a 0x5261af 0x526edf 0x5280ab 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
|
||||
2432 1 @ 0xbccc97 0xb82b73 0xb82bcb 0xb87eab 0xb8814c 0x7aa74c 0x7ab844 0x7ab914 0x79e9e9 0x79e326 0x4d299e 0x4d4b7b 0x4b7be8 0x4b7ff1 0x4d2dae 0x79e80a
|
||||
2034816 3 @ 0xbccc97 0xb82f0f 0xb83003 0xb87d50 0xc635f0 0x42ecc3 0x42e14c 0x5261af 0x526edf 0x5280ab 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
|
||||
--- Memory map: ---
|
||||
00400000-00fcb000: cppbench_server_main
|
||||
7fcdc231e000-7fcdc2321000: /libnss_cache-2.15.so
|
||||
7fcdc2522000-7fcdc252e000: /libnss_files-2.15.so
|
||||
7fcdc272f000-7fcdc28dd000: /libc-2.15.so
|
||||
7fcdc2ae7000-7fcdc2be2000: /libm-2.15.so
|
||||
7fcdc2de3000-7fcdc2dea000: /librt-2.15.so
|
||||
7fcdc2feb000-7fcdc3003000: /libpthread-2.15.so
|
||||
7fcdc3208000-7fcdc320a000: /libdl-2.15.so
|
||||
7fcdc340c000-7fcdc3415000: /libcrypt-2.15.so
|
||||
7fcdc3645000-7fcdc3669000: /ld-2.15.so
|
||||
7fff86bff000-7fff86c00000: [vdso]
|
||||
ffffffffff600000-ffffffffff601000: [vsyscall]
|
BIN
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.cpu
generated
vendored
BIN
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/cppbench.cpu
generated
vendored
Binary file not shown.
@ -1,19 +0,0 @@
|
||||
--- contentionz 1 ---
|
||||
cycles/second = 3201000000
|
||||
sampling period = 100
|
||||
ms since reset = 16502830
|
||||
discarded samples = 0
|
||||
100 10 @ 0xbccc97 0xc61202 0x42ed5f 0x42edc1 0x42e15a 0x5261af 0x526edf 0x5280ab 0x79e80a 0x7a251b 0x7a296d 0xa456e4 0x7fcdc2ff214e
|
||||
--- Memory map: ---
|
||||
00400000-00fcb000: cppbench_server_main
|
||||
7fcdc231e000-7fcdc2321000: /libnss_cache-2.15.so
|
||||
7fcdc2522000-7fcdc252e000: /libnss_files-2.15.so
|
||||
7fcdc272f000-7fcdc28dd000: /libc-2.15.so
|
||||
7fcdc2ae7000-7fcdc2be2000: /libm-2.15.so
|
||||
7fcdc2de3000-7fcdc2dea000: /librt-2.15.so
|
||||
7fcdc2feb000-7fcdc3003000: /libpthread-2.15.so
|
||||
7fcdc3208000-7fcdc320a000: /libdl-2.15.so
|
||||
7fcdc340c000-7fcdc3415000: /libcrypt-2.15.so
|
||||
7fcdc3645000-7fcdc3669000: /ld-2.15.so
|
||||
7fff86bff000-7fff86c00000: [vdso]
|
||||
ffffffffff600000-ffffffffff601000: [vsyscall]
|
17
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/file1000.src
generated
vendored
17
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/file1000.src
generated
vendored
@ -1,17 +0,0 @@
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4
|
||||
line5
|
||||
line6
|
||||
line7
|
||||
line8
|
||||
line9
|
||||
line0
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4
|
||||
line5
|
||||
|
||||
|
17
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/file2000.src
generated
vendored
17
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/file2000.src
generated
vendored
@ -1,17 +0,0 @@
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4
|
||||
line5
|
||||
line6
|
||||
line7
|
||||
line8
|
||||
line9
|
||||
line0
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4
|
||||
line5
|
||||
|
||||
|
17
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/file3000.src
generated
vendored
17
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/file3000.src
generated
vendored
@ -1,17 +0,0 @@
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4
|
||||
line5
|
||||
line6
|
||||
line7
|
||||
line8
|
||||
line9
|
||||
line0
|
||||
line1
|
||||
line2
|
||||
line3
|
||||
line4
|
||||
line5
|
||||
|
||||
|
BIN
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/go.crc32.cpu
generated
vendored
BIN
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/go.crc32.cpu
generated
vendored
Binary file not shown.
BIN
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/go.nomappings.crash
generated
vendored
BIN
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/go.nomappings.crash
generated
vendored
Binary file not shown.
@ -1,10 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid-contention" [shape=box fontsize=16 label="Build ID: buildid-contention\lComment #1\lComment #2\lType: delay\lShowing nodes accounting for 149.50ms, 100% of 149.50ms total\l"] }
|
||||
N1 [label="file3000.src\n32.77ms (21.92%)\nof 149.50ms (100%)" id="node1" fontsize=20 shape=box tooltip="testdata/file3000.src (149.50ms)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N2 [label="file1000.src\n51.20ms (34.25%)" id="node2" fontsize=23 shape=box tooltip="testdata/file1000.src (51.20ms)" color="#b23100" fillcolor="#eddbd5"]
|
||||
N3 [label="file2000.src\n65.54ms (43.84%)\nof 75.78ms (50.68%)" id="node3" fontsize=24 shape=box tooltip="testdata/file2000.src (75.78ms)" color="#b22000" fillcolor="#edd9d5"]
|
||||
N1 -> N3 [label=" 75.78ms" weight=51 penwidth=3 color="#b22000" tooltip="testdata/file3000.src -> testdata/file2000.src (75.78ms)" labeltooltip="testdata/file3000.src -> testdata/file2000.src (75.78ms)"]
|
||||
N1 -> N2 [label=" 40.96ms" weight=28 penwidth=2 color="#b23900" tooltip="testdata/file3000.src -> testdata/file1000.src (40.96ms)" labeltooltip="testdata/file3000.src -> testdata/file1000.src (40.96ms)"]
|
||||
N3 -> N2 [label=" 10.24ms" weight=7 color="#b29775" tooltip="testdata/file2000.src -> testdata/file1000.src (10.24ms)" labeltooltip="testdata/file2000.src -> testdata/file1000.src (10.24ms)"]
|
||||
}
|
@ -1,9 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid-contention" [shape=box fontsize=16 label="Build ID: buildid-contention\lComment #1\lComment #2\lType: delay\lActive filters:\l focus=[X1]000\l ignore=[X3]002\lShowing nodes accounting for 40.96ms, 27.40% of 149.50ms total\l"] }
|
||||
N1 [label="0000000000001000\nline1000\nfile1000.src:1\n40.96ms (27.40%)" id="node1" fontsize=24 shape=box tooltip="0000000000001000 line1000 testdata/file1000.src:1 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
|
||||
N2 [label="0000000000003001\nline3000\nfile3000.src:5\n0 of 40.96ms (27.40%)" id="node2" fontsize=8 shape=box tooltip="0000000000003001 line3000 testdata/file3000.src:5 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
|
||||
N3 [label="0000000000003001\nline3001\nfile3000.src:3\n0 of 40.96ms (27.40%)" id="node3" fontsize=8 shape=box tooltip="0000000000003001 line3001 testdata/file3000.src:3 (40.96ms)" color="#b23900" fillcolor="#edddd5"]
|
||||
N2 -> N3 [label=" 40.96ms\n (inline)" weight=28 penwidth=2 color="#b23900" tooltip="0000000000003001 line3000 testdata/file3000.src:5 -> 0000000000003001 line3001 testdata/file3000.src:3 (40.96ms)" labeltooltip="0000000000003001 line3000 testdata/file3000.src:5 -> 0000000000003001 line3001 testdata/file3000.src:3 (40.96ms)"]
|
||||
N3 -> N1 [label=" 40.96ms" weight=28 penwidth=2 color="#b23900" tooltip="0000000000003001 line3001 testdata/file3000.src:3 -> 0000000000001000 line1000 testdata/file1000.src:1 (40.96ms)" labeltooltip="0000000000003001 line3001 testdata/file3000.src:3 -> 0000000000001000 line1000 testdata/file1000.src:1 (40.96ms)"]
|
||||
}
|
@ -1,99 +0,0 @@
|
||||
positions: instr line
|
||||
events: cpu(ms)
|
||||
|
||||
ob=(1) /path/to/testbinary
|
||||
fl=(1) testdata/file1000.src
|
||||
fn=(1) line1000
|
||||
0x1000 1 1000
|
||||
* 1 100
|
||||
|
||||
ob=(1)
|
||||
fl=(2) testdata/file2000.src
|
||||
fn=(2) line2001
|
||||
+4096 9 10
|
||||
|
||||
ob=(1)
|
||||
fl=(3) testdata/file3000.src
|
||||
fn=(3) line3002
|
||||
+4096 2 10
|
||||
cfl=(2)
|
||||
cfn=(4) line2000 [1/2]
|
||||
calls=0 * 4
|
||||
* * 1000
|
||||
|
||||
ob=(1)
|
||||
fl=(2)
|
||||
fn=(5) line2000
|
||||
-4096 4 0
|
||||
cfl=(2)
|
||||
cfn=(6) line2001 [2/2]
|
||||
calls=0 -4096 9
|
||||
* * 1000
|
||||
* 4 0
|
||||
cfl=(2)
|
||||
cfn=(7) line2001 [1/2]
|
||||
calls=0 * 9
|
||||
* * 10
|
||||
|
||||
ob=(1)
|
||||
fl=(2)
|
||||
fn=(2)
|
||||
* 9 0
|
||||
cfl=(1)
|
||||
cfn=(8) line1000 [1/2]
|
||||
calls=0 -4096 1
|
||||
* * 1000
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(9) line3000
|
||||
+4096 6 0
|
||||
cfl=(3)
|
||||
cfn=(10) line3001 [1/2]
|
||||
calls=0 +4096 5
|
||||
* * 1010
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(11) line3001
|
||||
* 5 0
|
||||
cfl=(3)
|
||||
cfn=(12) line3002 [1/2]
|
||||
calls=0 * 2
|
||||
* * 1010
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(9)
|
||||
+1 9 0
|
||||
cfl=(3)
|
||||
cfn=(13) line3001 [2/2]
|
||||
calls=0 +1 8
|
||||
* * 100
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(11)
|
||||
* 8 0
|
||||
cfl=(1)
|
||||
cfn=(14) line1000 [2/2]
|
||||
calls=0 -8193 1
|
||||
* * 100
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(9)
|
||||
+1 9 0
|
||||
cfl=(3)
|
||||
cfn=(15) line3002 [2/2]
|
||||
calls=0 +1 5
|
||||
* * 10
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(3)
|
||||
* 5 0
|
||||
cfl=(2)
|
||||
cfn=(16) line2000 [2/2]
|
||||
calls=0 -4098 4
|
||||
* * 10
|
88
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.callgrind
generated
vendored
88
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.callgrind
generated
vendored
@ -1,88 +0,0 @@
|
||||
positions: instr line
|
||||
events: cpu(ms)
|
||||
|
||||
ob=(1) /path/to/testbinary
|
||||
fl=(1) testdata/file1000.src
|
||||
fn=(1) line1000
|
||||
0x1000 1 1100
|
||||
|
||||
ob=(1)
|
||||
fl=(2) testdata/file2000.src
|
||||
fn=(2) line2001
|
||||
+4096 9 10
|
||||
cfl=(1)
|
||||
cfn=(1)
|
||||
calls=0 * 1
|
||||
* * 1000
|
||||
|
||||
ob=(1)
|
||||
fl=(3) testdata/file3000.src
|
||||
fn=(3) line3002
|
||||
+4096 2 10
|
||||
cfl=(2)
|
||||
cfn=(4) line2000
|
||||
calls=0 * 4
|
||||
* * 1000
|
||||
|
||||
ob=(1)
|
||||
fl=(2)
|
||||
fn=(4)
|
||||
-4096 4 0
|
||||
cfl=(2)
|
||||
cfn=(2)
|
||||
calls=0 -4096 9
|
||||
* * 1010
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(5) line3000
|
||||
+4096 6 0
|
||||
cfl=(3)
|
||||
cfn=(6) line3001
|
||||
calls=0 +4096 5
|
||||
* * 1010
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(6)
|
||||
* 5 0
|
||||
cfl=(3)
|
||||
cfn=(3)
|
||||
calls=0 * 2
|
||||
* * 1010
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(5)
|
||||
+1 9 0
|
||||
cfl=(3)
|
||||
cfn=(6)
|
||||
calls=0 +1 8
|
||||
* * 100
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(6)
|
||||
* 8 0
|
||||
cfl=(1)
|
||||
cfn=(1)
|
||||
calls=0 -8193 1
|
||||
* * 100
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(5)
|
||||
+1 9 0
|
||||
cfl=(3)
|
||||
cfn=(3)
|
||||
calls=0 +1 5
|
||||
* * 10
|
||||
|
||||
ob=(1)
|
||||
fl=(3)
|
||||
fn=(3)
|
||||
* 5 0
|
||||
cfl=(2)
|
||||
cfn=(4)
|
||||
calls=0 -4098 4
|
||||
* * 10
|
1
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.comments
generated
vendored
1
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.comments
generated
vendored
@ -1 +0,0 @@
|
||||
some-comment
|
@ -1,8 +0,0 @@
|
||||
Active filters:
|
||||
focus=[12]00
|
||||
hide=line[X3]0
|
||||
Showing nodes accounting for 1.11s, 99.11% of 1.12s total
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 98.21% 98.21% 1.10s 98.21% line1000 testdata/file1000.src:1
|
||||
0 0% 98.21% 1.01s 90.18% line2000 testdata/file2000.src:4
|
||||
0.01s 0.89% 99.11% 1.01s 90.18% line2001 testdata/file2000.src:9 (inline)
|
@ -1,7 +0,0 @@
|
||||
Active filters:
|
||||
hide=line[X3]0
|
||||
Showing nodes accounting for 1.11s, 99.11% of 1.12s total
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 98.21% 98.21% 1.10s 98.21% line1000 testdata/file1000.src:1
|
||||
0 0% 98.21% 1.01s 90.18% line2000 testdata/file2000.src:4
|
||||
0.01s 0.89% 99.11% 1.01s 90.18% line2001 testdata/file2000.src:9 (inline)
|
@ -1,7 +0,0 @@
|
||||
Active filters:
|
||||
show=[12]00
|
||||
Showing nodes accounting for 1.11s, 99.11% of 1.12s total
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 98.21% 98.21% 1.10s 98.21% line1000 testdata/file1000.src:1
|
||||
0 0% 98.21% 1.01s 90.18% line2000 testdata/file2000.src:4
|
||||
0.01s 0.89% 99.11% 1.01s 90.18% line2001 testdata/file2000.src:9 (inline)
|
@ -1,5 +0,0 @@
|
||||
Active filters:
|
||||
hide=mangled[X3]0
|
||||
Showing nodes accounting for 1s, 100% of 1s total
|
||||
flat flat% sum% cum cum%
|
||||
1s 100% 100% 1s 100% mangled1000 testdata/file1000.src:1
|
@ -1,16 +0,0 @@
|
||||
Active filters:
|
||||
show_from=line2
|
||||
Showing nodes accounting for 1.01s, 90.18% of 1.12s total
|
||||
----------------------------------------------------------+-------------
|
||||
flat flat% sum% cum cum% calls calls% + context
|
||||
----------------------------------------------------------+-------------
|
||||
0 0% 0% 1.01s 90.18% | line2000 testdata/file2000.src:4
|
||||
1.01s 100% | line2001 testdata/file2000.src:9 (inline)
|
||||
----------------------------------------------------------+-------------
|
||||
1.01s 100% | line2000 testdata/file2000.src:4 (inline)
|
||||
0.01s 0.89% 0.89% 1.01s 90.18% | line2001 testdata/file2000.src:9
|
||||
1s 99.01% | line1000 testdata/file1000.src:1
|
||||
----------------------------------------------------------+-------------
|
||||
1s 100% | line2001 testdata/file2000.src:9
|
||||
1s 89.29% 90.18% 1s 89.29% | line1000 testdata/file1000.src:1
|
||||
----------------------------------------------------------+-------------
|
@ -1,14 +0,0 @@
|
||||
Total: 1.12s
|
||||
ROUTINE ======================== line1000
|
||||
1.10s 1.10s (flat, cum) 98.21% of Total
|
||||
1.10s 1.10s 1000: instruction one ;line1000 file1000.src:1
|
||||
. . 1001: instruction two ;file1000.src:1
|
||||
. . 1002: instruction three ;file1000.src:2
|
||||
. . 1003: instruction four ;file1000.src:1
|
||||
ROUTINE ======================== line3000
|
||||
10ms 1.12s (flat, cum) 100% of Total
|
||||
10ms 1.01s 3000: instruction one ;line3000 file3000.src:6
|
||||
. 100ms 3001: instruction two ;line3000 file3000.src:9
|
||||
. 10ms 3002: instruction three
|
||||
. . 3003: instruction four
|
||||
. . 3004: instruction five
|
@ -1,7 +0,0 @@
|
||||
Showing nodes accounting for 1.12s, 100% of 1.12s total
|
||||
Dropped 1 node (cum <= 0.06s)
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 98.21% 98.21% 1.10s 98.21% 0000000000001000 line1000 testdata/file1000.src:1
|
||||
0.01s 0.89% 99.11% 1.01s 90.18% 0000000000002000 line2000 testdata/file2000.src:4
|
||||
0.01s 0.89% 100% 1.01s 90.18% 0000000000003000 line3000 testdata/file3000.src:6
|
||||
0 0% 100% 0.10s 8.93% 0000000000003001 line3000 testdata/file3000.src:9
|
@ -1,106 +0,0 @@
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Pprof listing</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
h1 {
|
||||
font-size: 1.5em;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
.legend {
|
||||
font-size: 1.25em;
|
||||
}
|
||||
.line, .nop, .unimportant {
|
||||
color: #aaaaaa;
|
||||
}
|
||||
.inlinesrc {
|
||||
color: #000066;
|
||||
}
|
||||
.deadsrc {
|
||||
cursor: pointer;
|
||||
}
|
||||
.deadsrc:hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
.livesrc {
|
||||
color: #0000ff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.livesrc:hover {
|
||||
background-color: #eeeeee;
|
||||
}
|
||||
.asm {
|
||||
color: #008800;
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<script type="text/javascript">
|
||||
function pprof_toggle_asm(e) {
|
||||
var target;
|
||||
if (!e) e = window.event;
|
||||
if (e.target) target = e.target;
|
||||
else if (e.srcElement) target = e.srcElement;
|
||||
|
||||
if (target) {
|
||||
var asm = target.nextSibling;
|
||||
if (asm && asm.className == "asm") {
|
||||
asm.style.display = (asm.style.display == "block" ? "" : "block");
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="legend">File: testbinary<br>
|
||||
Type: cpu<br>
|
||||
Duration: 10s, Total samples = 1.12s (11.20%)<br>Total: 1.12s</div><h2>line1000</h2><p class="filename">testdata/file1000.src</p>
|
||||
<pre onClick="pprof_toggle_asm(event)">
|
||||
Total: 1.10s 1.10s (flat, cum) 98.21%
|
||||
<span class=line> 1</span> <span class=deadsrc> 1.10s 1.10s line1 </span><span class=asm> 1.10s 1.10s 1000: instruction one <span class=unimportant>file1000.src:1</span>
|
||||
. . 1001: instruction two <span class=unimportant>file1000.src:1</span>
|
||||
⋮
|
||||
. . 1003: instruction four <span class=unimportant>file1000.src:1</span>
|
||||
</span>
|
||||
<span class=line> 2</span> <span class=deadsrc> . . line2 </span><span class=asm> . . 1002: instruction three <span class=unimportant>file1000.src:2</span>
|
||||
</span>
|
||||
<span class=line> 3</span> <span class=nop> . . line3 </span>
|
||||
<span class=line> 4</span> <span class=nop> . . line4 </span>
|
||||
<span class=line> 5</span> <span class=nop> . . line5 </span>
|
||||
<span class=line> 6</span> <span class=nop> . . line6 </span>
|
||||
<span class=line> 7</span> <span class=nop> . . line7 </span>
|
||||
</pre>
|
||||
<h2>line3000</h2><p class="filename">testdata/file3000.src</p>
|
||||
<pre onClick="pprof_toggle_asm(event)">
|
||||
Total: 10ms 1.12s (flat, cum) 100%
|
||||
<span class=line> 1</span> <span class=nop> . . line1 </span>
|
||||
<span class=line> 2</span> <span class=nop> . . line2 </span>
|
||||
<span class=line> 3</span> <span class=nop> . . line3 </span>
|
||||
<span class=line> 4</span> <span class=nop> . . line4 </span>
|
||||
<span class=line> 5</span> <span class=nop> . . line5 </span>
|
||||
<span class=line> 6</span> <span class=deadsrc> 10ms 1.01s line6 </span><span class=asm> 10ms 1.01s 3000: instruction one <span class=unimportant>file3000.src:6</span>
|
||||
</span>
|
||||
<span class=line> 7</span> <span class=nop> . . line7 </span>
|
||||
<span class=line> 8</span> <span class=nop> . . line8 </span>
|
||||
<span class=line> 9</span> <span class=deadsrc> . 110ms line9 </span><span class=asm> . 100ms 3001: instruction two <span class=unimportant>file3000.src:9</span>
|
||||
. 10ms 3002: instruction three <span class=unimportant>file3000.src:9</span>
|
||||
. . 3003: instruction four <span class=unimportant></span>
|
||||
. . 3004: instruction five <span class=unimportant></span>
|
||||
</span>
|
||||
<span class=line> 10</span> <span class=nop> . . line0 </span>
|
||||
<span class=line> 11</span> <span class=nop> . . line1 </span>
|
||||
<span class=line> 12</span> <span class=nop> . . line2 </span>
|
||||
<span class=line> 13</span> <span class=nop> . . line3 </span>
|
||||
<span class=line> 14</span> <span class=nop> . . line4 </span>
|
||||
</pre>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,5 +0,0 @@
|
||||
Showing nodes accounting for 1.12s, 100% of 1.12s total
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 98.21% 98.21% 1.10s 98.21% line1000 testdata/file1000.src
|
||||
0.01s 0.89% 99.11% 1.01s 90.18% line2000 testdata/file2000.src
|
||||
0.01s 0.89% 100% 1.12s 100% line3000 testdata/file3000.src
|
@ -1,21 +0,0 @@
|
||||
digraph "testbinary" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "File: testbinary" [shape=box fontsize=16 label="File: testbinary\lType: cpu\lDuration: 10s, Total samples = 1.12s (11.20%)\lShowing nodes accounting for 1.11s, 99.11% of 1.12s total\lDropped 3 nodes (cum <= 0.06s)\l" tooltip="testbinary"] }
|
||||
N1 [label="line1000\n1s (89.29%)" id="node1" fontsize=24 shape=box tooltip="line1000 (1s)" color="#b20500" fillcolor="#edd6d5"]
|
||||
N1_0 [label = "key1:tag1\nkey2:tag1" id="N1_0" fontsize=8 shape=box3d tooltip="1s"]
|
||||
N1 -> N1_0 [label=" 1s" weight=100 tooltip="1s" labeltooltip="1s"]
|
||||
N2 [label="line3000\n0 of 1.12s (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (1.12s)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N3 [label="line3001\n0 of 1.11s (99.11%)" id="node3" fontsize=8 shape=box tooltip="line3001 (1.11s)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N4 [label="line1000\n0.10s (8.93%)" id="node4" fontsize=14 shape=box tooltip="line1000 (0.10s)" color="#b28b62" fillcolor="#ede8e2"]
|
||||
N4_0 [label = "key1:tag2\nkey3:tag2" id="N4_0" fontsize=8 shape=box3d tooltip="0.10s"]
|
||||
N4 -> N4_0 [label=" 0.10s" weight=100 tooltip="0.10s" labeltooltip="0.10s"]
|
||||
N5 [label="line3002\n0.01s (0.89%)\nof 1.01s (90.18%)" id="node5" fontsize=10 shape=box tooltip="line3002 (1.01s)" color="#b20500" fillcolor="#edd6d5"]
|
||||
N6 [label="line2000\n0 of 1s (89.29%)" id="node6" fontsize=8 shape=box tooltip="line2000 (1s)" color="#b20500" fillcolor="#edd6d5"]
|
||||
N7 [label="line2001\n0 of 1s (89.29%)" id="node7" fontsize=8 shape=box tooltip="line2001 (1s)" color="#b20500" fillcolor="#edd6d5"]
|
||||
N2 -> N3 [label=" 1.11s\n (inline)" weight=100 penwidth=5 color="#b20000" tooltip="line3000 -> line3001 (1.11s)" labeltooltip="line3000 -> line3001 (1.11s)"]
|
||||
N3 -> N5 [label=" 1.01s\n (inline)" weight=91 penwidth=5 color="#b20500" tooltip="line3001 -> line3002 (1.01s)" labeltooltip="line3001 -> line3002 (1.01s)"]
|
||||
N6 -> N7 [label=" 1s\n (inline)" weight=90 penwidth=5 color="#b20500" tooltip="line2000 -> line2001 (1s)" labeltooltip="line2000 -> line2001 (1s)"]
|
||||
N7 -> N1 [label=" 1s" weight=90 penwidth=5 color="#b20500" tooltip="line2001 -> line1000 (1s)" labeltooltip="line2001 -> line1000 (1s)"]
|
||||
N5 -> N6 [label=" 1s" weight=90 penwidth=5 color="#b20500" tooltip="line3002 -> line2000 (1s)" labeltooltip="line3002 -> line2000 (1s)"]
|
||||
N3 -> N4 [label=" 0.10s" weight=9 color="#b28b62" tooltip="line3001 -> line1000 (0.10s)" labeltooltip="line3001 -> line1000 (0.10s)"]
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
digraph "testbinary" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "File: testbinary" [shape=box fontsize=16 label="File: testbinary\lType: cpu\lDuration: 10s, Total samples = 1.12s (11.20%)\lShowing nodes accounting for 1.12s, 100% of 1.12s total\l" tooltip="testbinary"] }
|
||||
N1 [label="line1000\n1.10s (98.21%)" id="node1" fontsize=24 shape=box tooltip="line1000 (1.10s)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N1_0 [label = "key1:tag1\nkey2:tag1" id="N1_0" fontsize=8 shape=box3d tooltip="1s"]
|
||||
N1 -> N1_0 [label=" 1s" weight=100 tooltip="1s" labeltooltip="1s"]
|
||||
N1_1 [label = "key1:tag2\nkey3:tag2" id="N1_1" fontsize=8 shape=box3d tooltip="0.10s"]
|
||||
N1 -> N1_1 [label=" 0.10s" weight=100 tooltip="0.10s" labeltooltip="0.10s"]
|
||||
N2 [label="line3000\n0 of 1.12s (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (1.12s)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N3 [label="line3001\n0 of 1.11s (99.11%)" id="node3" fontsize=8 shape=box tooltip="line3001 (1.11s)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N4 [label="line3002\n0.01s (0.89%)\nof 1.02s (91.07%)" id="node4" fontsize=10 shape=box tooltip="line3002 (1.02s)" color="#b20400" fillcolor="#edd6d5"]
|
||||
N5 [label="line2001\n0.01s (0.89%)\nof 1.01s (90.18%)" id="node5" fontsize=10 shape=box tooltip="line2001 (1.01s)" color="#b20500" fillcolor="#edd6d5"]
|
||||
N6 [label="line2000\n0 of 1.01s (90.18%)" id="node6" fontsize=8 shape=box tooltip="line2000 (1.01s)" color="#b20500" fillcolor="#edd6d5"]
|
||||
N2 -> N3 [label=" 1.11s\n (inline)" weight=100 penwidth=5 color="#b20000" tooltip="line3000 -> line3001 (1.11s)" labeltooltip="line3000 -> line3001 (1.11s)"]
|
||||
N6 -> N5 [label=" 1.01s\n (inline)" weight=91 penwidth=5 color="#b20500" tooltip="line2000 -> line2001 (1.01s)" labeltooltip="line2000 -> line2001 (1.01s)"]
|
||||
N3 -> N4 [label=" 1.01s\n (inline)" weight=91 penwidth=5 color="#b20500" tooltip="line3001 -> line3002 (1.01s)" labeltooltip="line3001 -> line3002 (1.01s)"]
|
||||
N4 -> N6 [label=" 1.01s" weight=91 penwidth=5 color="#b20500" tooltip="line3002 -> line2000 (1.01s)" labeltooltip="line3002 -> line2000 (1.01s)"]
|
||||
N5 -> N1 [label=" 1s" weight=90 penwidth=5 color="#b20500" tooltip="line2001 -> line1000 (1s)" labeltooltip="line2001 -> line1000 (1s)"]
|
||||
N3 -> N1 [label=" 0.10s" weight=9 color="#b28b62" tooltip="line3001 -> line1000 (0.10s)" labeltooltip="line3001 -> line1000 (0.10s)"]
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
Showing nodes accounting for 1.12s, 100% of 1.12s total
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 98.21% 98.21% 1.10s 98.21% line1000
|
||||
0.01s 0.89% 99.11% 1.01s 90.18% line2000
|
||||
0.01s 0.89% 100% 1.12s 100% line3000
|
@ -1,8 +0,0 @@
|
||||
Showing nodes accounting for 1.12s, 100% of 1.12s total
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 98.21% 98.21% 1.10s 98.21% line1000
|
||||
0.01s 0.89% 99.11% 1.01s 90.18% line2001 (inline)
|
||||
0.01s 0.89% 100% 1.02s 91.07% line3002 (inline)
|
||||
0 0% 100% 1.01s 90.18% line2000
|
||||
0 0% 100% 1.12s 100% line3000
|
||||
0 0% 100% 1.11s 99.11% line3001 (inline)
|
@ -1,3 +0,0 @@
|
||||
Showing nodes accounting for 1s, 100% of 1s total
|
||||
flat flat% sum% cum cum%
|
||||
1s 100% 100% 1s 100% mangled1000 testdata/file1000.src:1
|
13
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.peek
generated
vendored
13
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.peek
generated
vendored
@ -1,13 +0,0 @@
|
||||
Showing nodes accounting for 1.12s, 100% of 1.12s total
|
||||
----------------------------------------------------------+-------------
|
||||
flat flat% sum% cum cum% calls calls% + context
|
||||
----------------------------------------------------------+-------------
|
||||
1.01s 100% | line2000 (inline)
|
||||
0.01s 0.89% 0.89% 1.01s 90.18% | line2001
|
||||
1s 99.01% | line1000
|
||||
----------------------------------------------------------+-------------
|
||||
1.11s 100% | line3000 (inline)
|
||||
0 0% 0.89% 1.11s 99.11% | line3001
|
||||
1.01s 90.99% | line3002 (inline)
|
||||
0.10s 9.01% | line1000
|
||||
----------------------------------------------------------+-------------
|
13
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags
generated
vendored
13
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.tags
generated
vendored
@ -1,13 +0,0 @@
|
||||
key1: Total 1.1s
|
||||
1.0s (89.29%): tag1
|
||||
100.0ms ( 8.93%): tag2
|
||||
10.0ms ( 0.89%): tag3
|
||||
10.0ms ( 0.89%): tag4
|
||||
|
||||
key2: Total 1.0s
|
||||
1.0s (99.02%): tag1
|
||||
10.0ms ( 0.98%): tag2
|
||||
|
||||
key3: Total 100.0ms
|
||||
100.0ms ( 100%): tag2
|
||||
|
@ -1,6 +0,0 @@
|
||||
key1: Total 100.0ms
|
||||
100.0ms ( 100%): tag2
|
||||
|
||||
key3: Total 100.0ms
|
||||
100.0ms ( 100%): tag2
|
||||
|
32
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.traces
generated
vendored
32
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.cpu.traces
generated
vendored
@ -1,32 +0,0 @@
|
||||
File: testbinary
|
||||
Type: cpu
|
||||
Duration: 10s, Total samples = 1.12s (11.20%)
|
||||
-----------+-------------------------------------------------------
|
||||
key1: tag1
|
||||
key2: tag1
|
||||
1s line1000
|
||||
line2001
|
||||
line2000
|
||||
line3002
|
||||
line3001
|
||||
line3000
|
||||
-----------+-------------------------------------------------------
|
||||
key1: tag2
|
||||
key3: tag2
|
||||
100ms line1000
|
||||
line3001
|
||||
line3000
|
||||
-----------+-------------------------------------------------------
|
||||
key1: tag3
|
||||
key2: tag2
|
||||
10ms line2001
|
||||
line2000
|
||||
line3002
|
||||
line3000
|
||||
-----------+-------------------------------------------------------
|
||||
key1: tag4
|
||||
key2: tag1
|
||||
10ms line3002
|
||||
line3001
|
||||
line3000
|
||||
-----------+-------------------------------------------------------
|
@ -1,17 +0,0 @@
|
||||
Showing nodes accounting for 4s, 100% of 4s total
|
||||
Showing top 4 nodes out of 5
|
||||
----------------------------------------------------------+-------------
|
||||
flat flat% sum% cum cum% calls calls% + context
|
||||
----------------------------------------------------------+-------------
|
||||
1s 100% | 0000000000003000 [testbinary]
|
||||
1s 25.00% 25.00% 1s 25.00% | 0000000000001000 [testbinary]
|
||||
----------------------------------------------------------+-------------
|
||||
1s 25.00% 50.00% 2s 50.00% | 0000000000003000 [testbinary]
|
||||
1s 50.00% | 0000000000001000 [testbinary]
|
||||
----------------------------------------------------------+-------------
|
||||
1s 100% | 0000000000005000 [testbinary]
|
||||
1s 25.00% 75.00% 1s 25.00% | 0000000000004000 [testbinary]
|
||||
----------------------------------------------------------+-------------
|
||||
1s 25.00% 100% 2s 50.00% | 0000000000005000 [testbinary]
|
||||
1s 50.00% | 0000000000004000 [testbinary]
|
||||
----------------------------------------------------------+-------------
|
88
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.callgrind
generated
vendored
88
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.callgrind
generated
vendored
@ -1,88 +0,0 @@
|
||||
positions: instr line
|
||||
events: inuse_space(MB)
|
||||
|
||||
ob=
|
||||
fl=(1) testdata/file2000.src
|
||||
fn=(1) line2001
|
||||
0x2000 2 62
|
||||
cfl=(2) testdata/file1000.src
|
||||
cfn=(2) line1000
|
||||
calls=0 0x1000 1
|
||||
* * 0
|
||||
|
||||
ob=
|
||||
fl=(3) testdata/file3000.src
|
||||
fn=(3) line3002
|
||||
+4096 3 31
|
||||
cfl=(1)
|
||||
cfn=(4) line2000
|
||||
calls=0 * 3
|
||||
* * 0
|
||||
|
||||
ob=
|
||||
fl=(2)
|
||||
fn=(2)
|
||||
-8192 1 4
|
||||
|
||||
ob=
|
||||
fl=(1)
|
||||
fn=(4)
|
||||
+4096 3 0
|
||||
cfl=(1)
|
||||
cfn=(1)
|
||||
calls=0 +4096 2
|
||||
* * 63
|
||||
|
||||
ob=
|
||||
fl=(3)
|
||||
fn=(5) line3000
|
||||
+4096 4 0
|
||||
cfl=(3)
|
||||
cfn=(6) line3001
|
||||
calls=0 +4096 2
|
||||
* * 32
|
||||
|
||||
ob=
|
||||
fl=(3)
|
||||
fn=(6)
|
||||
* 2 0
|
||||
cfl=(3)
|
||||
cfn=(3)
|
||||
calls=0 * 3
|
||||
* * 32
|
||||
|
||||
ob=
|
||||
fl=(3)
|
||||
fn=(5)
|
||||
+1 4 0
|
||||
cfl=(3)
|
||||
cfn=(6)
|
||||
calls=0 +1 2
|
||||
* * 3
|
||||
|
||||
ob=
|
||||
fl=(3)
|
||||
fn=(6)
|
||||
* 2 0
|
||||
cfl=(2)
|
||||
cfn=(2)
|
||||
calls=0 -8193 1
|
||||
* * 3
|
||||
|
||||
ob=
|
||||
fl=(3)
|
||||
fn=(5)
|
||||
+1 4 0
|
||||
cfl=(3)
|
||||
cfn=(3)
|
||||
calls=0 +1 3
|
||||
* * 62
|
||||
|
||||
ob=
|
||||
fl=(3)
|
||||
fn=(3)
|
||||
* 3 0
|
||||
cfl=(1)
|
||||
cfn=(4)
|
||||
calls=0 -4098 3
|
||||
* * 62
|
2
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.comments
generated
vendored
2
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.comments
generated
vendored
@ -1,2 +0,0 @@
|
||||
comment
|
||||
#hidden comment
|
@ -1,21 +0,0 @@
|
||||
Active filters:
|
||||
focus=[24]00
|
||||
Showing nodes accounting for 62.50MB, 63.37% of 98.63MB total
|
||||
Dropped 2 nodes (cum <= 4.93MB)
|
||||
----------------------------------------------------------+-------------
|
||||
flat flat% sum% cum cum% calls calls% + context
|
||||
----------------------------------------------------------+-------------
|
||||
63.48MB 100% | line3002 testdata/file3000.src:3
|
||||
0 0% 0% 63.48MB 64.36% | line2000 testdata/file2000.src:3
|
||||
63.48MB 100% | line2001 testdata/file2000.src:2 (inline)
|
||||
----------------------------------------------------------+-------------
|
||||
63.48MB 100% | line2000 testdata/file2000.src:3 (inline)
|
||||
62.50MB 63.37% 63.37% 63.48MB 64.36% | line2001 testdata/file2000.src:2
|
||||
----------------------------------------------------------+-------------
|
||||
0 0% 63.37% 63.48MB 64.36% | line3000 testdata/file3000.src:4
|
||||
63.48MB 100% | line3002 testdata/file3000.src:3 (inline)
|
||||
----------------------------------------------------------+-------------
|
||||
63.48MB 100% | line3000 testdata/file3000.src:4 (inline)
|
||||
0 0% 63.37% 63.48MB 64.36% | line3002 testdata/file3000.src:3
|
||||
63.48MB 100% | line2000 testdata/file2000.src:3
|
||||
----------------------------------------------------------+-------------
|
@ -1,21 +0,0 @@
|
||||
Active filters:
|
||||
focus=[24]00
|
||||
Showing nodes accounting for 62.50MB, 98.46% of 63.48MB total
|
||||
Dropped 2 nodes (cum <= 3.17MB)
|
||||
----------------------------------------------------------+-------------
|
||||
flat flat% sum% cum cum% calls calls% + context
|
||||
----------------------------------------------------------+-------------
|
||||
63.48MB 100% | line3002
|
||||
0 0% 0% 63.48MB 100% | line2000
|
||||
63.48MB 100% | line2001 (inline)
|
||||
----------------------------------------------------------+-------------
|
||||
63.48MB 100% | line2000 (inline)
|
||||
62.50MB 98.46% 98.46% 63.48MB 100% | line2001
|
||||
----------------------------------------------------------+-------------
|
||||
0 0% 98.46% 63.48MB 100% | line3000
|
||||
63.48MB 100% | line3002 (inline)
|
||||
----------------------------------------------------------+-------------
|
||||
63.48MB 100% | line3000 (inline)
|
||||
0 0% 98.46% 63.48MB 100% | line3002
|
||||
63.48MB 100% | line2000
|
||||
----------------------------------------------------------+-------------
|
@ -1,2 +0,0 @@
|
||||
Showing nodes accounting for 0, 0% of 0 total
|
||||
flat flat% sum% cum cum%
|
@ -1,5 +0,0 @@
|
||||
Showing nodes accounting for 93.75MB, 95.05% of 98.63MB total
|
||||
Dropped 1 node (cum <= 4.93MB)
|
||||
flat flat% sum% cum cum%
|
||||
62.50MB 63.37% 63.37% 63.48MB 64.36% testdata/file2000.src
|
||||
31.25MB 31.68% 95.05% 98.63MB 100% testdata/file3000.src
|
@ -1,8 +0,0 @@
|
||||
Active filters:
|
||||
focus=[12]00
|
||||
taghide=[X3]00
|
||||
Showing nodes accounting for 67.38MB, 68.32% of 98.63MB total
|
||||
flat flat% sum% cum cum%
|
||||
62.50MB 63.37% 63.37% 63.48MB 64.36% testdata/file2000.src
|
||||
4.88MB 4.95% 68.32% 4.88MB 4.95% testdata/file1000.src
|
||||
0 0% 68.32% 67.38MB 68.32% testdata/file3000.src
|
@ -1,8 +0,0 @@
|
||||
Showing nodes accounting for 150, 100% of 150 total
|
||||
flat flat% sum% cum cum%
|
||||
80 53.33% 53.33% 130 86.67% line3002 (inline)
|
||||
40 26.67% 80.00% 50 33.33% line2001 (inline)
|
||||
30 20.00% 100% 30 20.00% line1000
|
||||
0 0% 100% 50 33.33% line2000
|
||||
0 0% 100% 150 100% line3000
|
||||
0 0% 100% 110 73.33% line3001 (inline)
|
@ -1,13 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lActive filters:\l tagfocus=1mb:2gb\lShowing nodes accounting for 62.50MB, 63.37% of 98.63MB total\l"] }
|
||||
N1 [label="line2001\n62.50MB (63.37%)" id="node1" fontsize=24 shape=box tooltip="line2001 (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
NN1_0 [label = "1.56MB" id="NN1_0" fontsize=8 shape=box3d tooltip="62.50MB"]
|
||||
N1 -> NN1_0 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
|
||||
N2 [label="line3000\n0 of 62.50MB (63.37%)" id="node2" fontsize=8 shape=box tooltip="line3000 (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N3 [label="line2000\n0 of 62.50MB (63.37%)" id="node3" fontsize=8 shape=box tooltip="line2000 (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N4 [label="line3002\n0 of 62.50MB (63.37%)" id="node4" fontsize=8 shape=box tooltip="line3002 (62.50MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N3 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line2000 -> line2001 (62.50MB)" labeltooltip="line2000 -> line2001 (62.50MB)"]
|
||||
N2 -> N4 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 -> line3002 (62.50MB)" labeltooltip="line3000 -> line3002 (62.50MB)"]
|
||||
N4 -> N3 [label=" 62.50MB" weight=64 penwidth=4 color="#b21600" tooltip="line3002 -> line2000 (62.50MB)" labeltooltip="line3002 -> line2000 (62.50MB)"]
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lActive filters:\l tagfocus=30kb:\l tagignore=1mb:2mb\lShowing nodes accounting for 36.13MB, 36.63% of 98.63MB total\lDropped 2 nodes (cum <= 4.93MB)\l"] }
|
||||
N1 [label="line3002\n31.25MB (31.68%)\nof 32.23MB (32.67%)" id="node1" fontsize=24 shape=box tooltip="line3002 (32.23MB)" color="#b23200" fillcolor="#eddcd5"]
|
||||
NN1_0 [label = "400kB" id="NN1_0" fontsize=8 shape=box3d tooltip="31.25MB"]
|
||||
N1 -> NN1_0 [label=" 31.25MB" weight=100 tooltip="31.25MB" labeltooltip="31.25MB"]
|
||||
N2 [label="line3000\n0 of 36.13MB (36.63%)" id="node2" fontsize=8 shape=box tooltip="line3000 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
|
||||
N3 [label="line3001\n0 of 36.13MB (36.63%)" id="node3" fontsize=8 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
|
||||
N4 [label="line1000\n4.88MB (4.95%)" id="node4" fontsize=15 shape=box tooltip="line1000 (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
|
||||
NN4_0 [label = "200kB" id="NN4_0" fontsize=8 shape=box3d tooltip="3.91MB"]
|
||||
N4 -> NN4_0 [label=" 3.91MB" weight=100 tooltip="3.91MB" labeltooltip="3.91MB"]
|
||||
N2 -> N3 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)"]
|
||||
N3 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 -> line3002 (32.23MB)" labeltooltip="line3001 -> line3002 (32.23MB)"]
|
||||
N3 -> N4 [label=" 3.91MB" weight=4 color="#b2a58f" tooltip="line3001 -> line1000 (3.91MB)" labeltooltip="line3001 -> line1000 (3.91MB)"]
|
||||
N1 -> N4 [label=" 0.98MB" color="#b2b0a9" tooltip="line3002 ... line1000 (0.98MB)" labeltooltip="line3002 ... line1000 (0.98MB)" style="dotted" minlen=2]
|
||||
}
|
@ -1,21 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lActive filters:\l focus=[12]00\lShowing nodes accounting for 67.38MB, 68.32% of 98.63MB total\l"] }
|
||||
N1 [label="line3000\nfile3000.src:4\n0 of 67.38MB (68.32%)" id="node1" fontsize=8 shape=box tooltip="line3000 testdata/file3000.src:4 (67.38MB)" color="#b21300" fillcolor="#edd7d5"]
|
||||
N2 [label="line2001\nfile2000.src:2\n62.50MB (63.37%)\nof 63.48MB (64.36%)" id="node2" fontsize=24 shape=box tooltip="line2001 testdata/file2000.src:2 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
NN2_0 [label = "1.56MB" id="NN2_0" fontsize=8 shape=box3d tooltip="62.50MB"]
|
||||
N2 -> NN2_0 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
|
||||
N3 [label="line1000\nfile1000.src:1\n4.88MB (4.95%)" id="node3" fontsize=13 shape=box tooltip="line1000 testdata/file1000.src:1 (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
|
||||
NN3_0 [label = "200kB" id="NN3_0" fontsize=8 shape=box3d tooltip="3.91MB"]
|
||||
N3 -> NN3_0 [label=" 3.91MB" weight=100 tooltip="3.91MB" labeltooltip="3.91MB"]
|
||||
N4 [label="line3002\nfile3000.src:3\n0 of 63.48MB (64.36%)" id="node4" fontsize=8 shape=box tooltip="line3002 testdata/file3000.src:3 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N5 [label="line3001\nfile3000.src:2\n0 of 4.88MB (4.95%)" id="node5" fontsize=8 shape=box tooltip="line3001 testdata/file3000.src:2 (4.88MB)" color="#b2a086" fillcolor="#edeae7"]
|
||||
N6 [label="line2000\nfile2000.src:3\n0 of 63.48MB (64.36%)" id="node6" fontsize=8 shape=box tooltip="line2000 testdata/file2000.src:3 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N6 -> N2 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 testdata/file2000.src:3 -> line2001 testdata/file2000.src:2 (63.48MB)" labeltooltip="line2000 testdata/file2000.src:3 -> line2001 testdata/file2000.src:2 (63.48MB)"]
|
||||
N4 -> N6 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 testdata/file3000.src:3 -> line2000 testdata/file2000.src:3 (63.48MB)" labeltooltip="line3002 testdata/file3000.src:3 -> line2000 testdata/file2000.src:3 (63.48MB)"]
|
||||
N1 -> N4 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 testdata/file3000.src:4 -> line3002 testdata/file3000.src:3 (62.50MB)" labeltooltip="line3000 testdata/file3000.src:4 -> line3002 testdata/file3000.src:3 (62.50MB)"]
|
||||
N1 -> N5 [label=" 4.88MB\n (inline)" weight=5 color="#b2a086" tooltip="line3000 testdata/file3000.src:4 -> line3001 testdata/file3000.src:2 (4.88MB)" labeltooltip="line3000 testdata/file3000.src:4 -> line3001 testdata/file3000.src:2 (4.88MB)"]
|
||||
N5 -> N3 [label=" 3.91MB" weight=4 color="#b2a58f" tooltip="line3001 testdata/file3000.src:2 -> line1000 testdata/file1000.src:1 (3.91MB)" labeltooltip="line3001 testdata/file3000.src:2 -> line1000 testdata/file1000.src:1 (3.91MB)"]
|
||||
N2 -> N3 [label=" 0.98MB" color="#b2b0a9" tooltip="line2001 testdata/file2000.src:2 -> line1000 testdata/file1000.src:1 (0.98MB)" labeltooltip="line2001 testdata/file2000.src:2 -> line1000 testdata/file1000.src:1 (0.98MB)" minlen=2]
|
||||
N5 -> N4 [label=" 0.98MB\n (inline)" color="#b2b0a9" tooltip="line3001 testdata/file3000.src:2 -> line3002 testdata/file3000.src:3 (0.98MB)" labeltooltip="line3001 testdata/file3000.src:2 -> line3002 testdata/file3000.src:3 (0.98MB)"]
|
||||
}
|
6
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags
generated
vendored
6
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags
generated
vendored
@ -1,6 +0,0 @@
|
||||
bytes: Total 98.6MB
|
||||
62.5MB (63.37%): 1.56MB
|
||||
31.2MB (31.68%): 400kB
|
||||
3.9MB ( 3.96%): 200kB
|
||||
1000.0kB ( 0.99%): 100kB
|
||||
|
6
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags.unit
generated
vendored
6
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap.tags.unit
generated
vendored
@ -1,6 +0,0 @@
|
||||
bytes: Total 103424000.0B
|
||||
65536000.0B (63.37%): 1638400B
|
||||
32768000.0B (31.68%): 409600B
|
||||
4096000.0B ( 3.96%): 204800B
|
||||
1024000.0B ( 0.99%): 102400B
|
||||
|
@ -1,8 +0,0 @@
|
||||
Showing nodes accounting for 150, 100% of 150 total
|
||||
flat flat% sum% cum cum%
|
||||
80 53.33% 53.33% 130 86.67% line3002 (inline)
|
||||
40 26.67% 80.00% 50 33.33% line2001 (inline)
|
||||
30 20.00% 100% 30 20.00% line1000
|
||||
0 0% 100% 50 33.33% line2000
|
||||
0 0% 100% 150 100% line3000
|
||||
0 0% 100% 110 73.33% line3001 (inline)
|
@ -1,14 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: alloc_space\lActive filters:\l tagshow=[2]00\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
|
||||
N1 [label="line3002\n31.25MB (31.68%)\nof 94.73MB (96.04%)" id="node1" fontsize=20 shape=box tooltip="line3002 (94.73MB)" color="#b20200" fillcolor="#edd5d5"]
|
||||
N2 [label="line3000\n0 of 98.63MB (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N3 [label="line2001\n62.50MB (63.37%)\nof 63.48MB (64.36%)" id="node3" fontsize=24 shape=box tooltip="line2001 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N4 [label="line2000\n0 of 63.48MB (64.36%)" id="node4" fontsize=8 shape=box tooltip="line2000 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N5 [label="line3001\n0 of 36.13MB (36.63%)" id="node5" fontsize=8 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
|
||||
N4 -> N3 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 -> line2001 (63.48MB)" labeltooltip="line2000 -> line2001 (63.48MB)"]
|
||||
N1 -> N4 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 -> line2000 (63.48MB)" labeltooltip="line3002 -> line2000 (63.48MB)"]
|
||||
N2 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 -> line3002 (62.50MB)" labeltooltip="line3000 -> line3002 (62.50MB)"]
|
||||
N2 -> N5 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)"]
|
||||
N5 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 -> line3002 (32.23MB)" labeltooltip="line3001 -> line3002 (32.23MB)"]
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: alloc_space\lActive filters:\l focus=[234]00\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
|
||||
N1 [label="line3002\n31.25MB (31.68%)\nof 94.73MB (96.04%)" id="node1" fontsize=20 shape=box tooltip="line3002 (94.73MB)" color="#b20200" fillcolor="#edd5d5"]
|
||||
NN1_0 [label = "400kB" id="NN1_0" fontsize=8 shape=box3d tooltip="31.25MB"]
|
||||
N1 -> NN1_0 [label=" 31.25MB" weight=100 tooltip="31.25MB" labeltooltip="31.25MB"]
|
||||
N2 [label="line3000\n0 of 98.63MB (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N3 [label="line2001\n62.50MB (63.37%)\nof 63.48MB (64.36%)" id="node3" fontsize=24 shape=box tooltip="line2001 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
NN3_0 [label = "1.56MB" id="NN3_0" fontsize=8 shape=box3d tooltip="62.50MB"]
|
||||
N3 -> NN3_0 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
|
||||
N4 [label="line2000\n0 of 63.48MB (64.36%)" id="node4" fontsize=8 shape=box tooltip="line2000 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N5 [label="line3001\n0 of 36.13MB (36.63%)" id="node5" fontsize=8 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
|
||||
N4 -> N3 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 -> line2001 (63.48MB)" labeltooltip="line2000 -> line2001 (63.48MB)"]
|
||||
N1 -> N4 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 -> line2000 (63.48MB)" labeltooltip="line3002 -> line2000 (63.48MB)" minlen=2]
|
||||
N2 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 -> line3002 (62.50MB)" labeltooltip="line3000 -> line3002 (62.50MB)"]
|
||||
N2 -> N5 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)"]
|
||||
N5 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 -> line3002 (32.23MB)" labeltooltip="line3001 -> line3002 (32.23MB)"]
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: alloc_space\lActive filters:\l hide=line.*1?23?\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
|
||||
N1 [label="line3000\n62.50MB (63.37%)\nof 98.63MB (100%)" id="node1" fontsize=24 shape=box tooltip="line3000 (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
|
||||
NN1_0 [label = "1.56MB" id="NN1_0" fontsize=8 shape=box3d tooltip="62.50MB"]
|
||||
N1 -> NN1_0 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
|
||||
N2 [label="line3001\n31.25MB (31.68%)\nof 36.13MB (36.63%)" id="node2" fontsize=20 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
|
||||
NN2_0 [label = "400kB" id="NN2_0" fontsize=8 shape=box3d tooltip="31.25MB"]
|
||||
N2 -> NN2_0 [label=" 31.25MB" weight=100 tooltip="31.25MB" labeltooltip="31.25MB"]
|
||||
N1 -> N2 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)" minlen=2]
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
bytes: Total 93.8MB
|
||||
62.5MB (66.67%): 1.56MB
|
||||
31.2MB (33.33%): 400kB
|
||||
|
||||
request: Total 93.8MB
|
||||
62.5MB (66.67%): 1.56MB
|
||||
31.2MB (33.33%): 400kB
|
||||
|
30
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_sizetags.dot
generated
vendored
30
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_sizetags.dot
generated
vendored
@ -1,30 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Build ID: buildid" [shape=box fontsize=16 label="Build ID: buildid\lcomment\lType: inuse_space\lShowing nodes accounting for 93.75MB, 95.05% of 98.63MB total\lDropped 1 node (cum <= 4.93MB)\l"] }
|
||||
N1 [label="line3002\n31.25MB (31.68%)\nof 94.73MB (96.04%)" id="node1" fontsize=20 shape=box tooltip="line3002 (94.73MB)" color="#b20200" fillcolor="#edd5d5"]
|
||||
NN1_0 [label = "16B..64B" id="NN1_0" fontsize=8 shape=box3d tooltip="93.75MB"]
|
||||
N1 -> NN1_0 [label=" 93.75MB" weight=100 tooltip="93.75MB" labeltooltip="93.75MB"]
|
||||
NN1_1 [label = "2B..8B" id="NN1_1" fontsize=8 shape=box3d tooltip="93.75MB"]
|
||||
N1 -> NN1_1 [label=" 93.75MB" weight=100 tooltip="93.75MB" labeltooltip="93.75MB"]
|
||||
NN1_2 [label = "256B..1.56MB" id="NN1_2" fontsize=8 shape=box3d tooltip="62.50MB"]
|
||||
N1 -> NN1_2 [label=" 62.50MB" weight=100 tooltip="62.50MB" labeltooltip="62.50MB"]
|
||||
NN1_3 [label = "128B" id="NN1_3" fontsize=8 shape=box3d tooltip="31.25MB"]
|
||||
N1 -> NN1_3 [label=" 31.25MB" weight=100 tooltip="31.25MB" labeltooltip="31.25MB"]
|
||||
N2 [label="line3000\n0 of 98.63MB (100%)" id="node2" fontsize=8 shape=box tooltip="line3000 (98.63MB)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N3 [label="line2001\n62.50MB (63.37%)\nof 63.48MB (64.36%)" id="node3" fontsize=24 shape=box tooltip="line2001 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
NN3_0 [label = "16B..64B" id="NN3_0" fontsize=8 shape=box3d tooltip="190.43MB"]
|
||||
N3 -> NN3_0 [label=" 190.43MB" weight=100 tooltip="190.43MB" labeltooltip="190.43MB" style="dotted"]
|
||||
NN3_1 [label = "2B..8B" id="NN3_1" fontsize=8 shape=box3d tooltip="190.43MB"]
|
||||
N3 -> NN3_1 [label=" 190.43MB" weight=100 tooltip="190.43MB" labeltooltip="190.43MB" style="dotted"]
|
||||
NN3_2 [label = "256B..1.56MB" id="NN3_2" fontsize=8 shape=box3d tooltip="125.98MB"]
|
||||
N3 -> NN3_2 [label=" 125.98MB" weight=100 tooltip="125.98MB" labeltooltip="125.98MB" style="dotted"]
|
||||
NN3_3 [label = "128B" id="NN3_3" fontsize=8 shape=box3d tooltip="63.48MB"]
|
||||
N3 -> NN3_3 [label=" 63.48MB" weight=100 tooltip="63.48MB" labeltooltip="63.48MB" style="dotted"]
|
||||
N4 [label="line2000\n0 of 63.48MB (64.36%)" id="node4" fontsize=8 shape=box tooltip="line2000 (63.48MB)" color="#b21600" fillcolor="#edd8d5"]
|
||||
N5 [label="line3001\n0 of 36.13MB (36.63%)" id="node5" fontsize=8 shape=box tooltip="line3001 (36.13MB)" color="#b22e00" fillcolor="#eddbd5"]
|
||||
N4 -> N3 [label=" 63.48MB\n (inline)" weight=65 penwidth=4 color="#b21600" tooltip="line2000 -> line2001 (63.48MB)" labeltooltip="line2000 -> line2001 (63.48MB)"]
|
||||
N1 -> N4 [label=" 63.48MB" weight=65 penwidth=4 color="#b21600" tooltip="line3002 -> line2000 (63.48MB)" labeltooltip="line3002 -> line2000 (63.48MB)" minlen=2]
|
||||
N2 -> N1 [label=" 62.50MB\n (inline)" weight=64 penwidth=4 color="#b21600" tooltip="line3000 -> line3002 (62.50MB)" labeltooltip="line3000 -> line3002 (62.50MB)"]
|
||||
N2 -> N5 [label=" 36.13MB\n (inline)" weight=37 penwidth=2 color="#b22e00" tooltip="line3000 -> line3001 (36.13MB)" labeltooltip="line3000 -> line3001 (36.13MB)"]
|
||||
N5 -> N1 [label=" 32.23MB\n (inline)" weight=33 penwidth=2 color="#b23200" tooltip="line3001 -> line3002 (32.23MB)" labeltooltip="line3001 -> line3002 (32.23MB)"]
|
||||
}
|
32
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_tags.traces
generated
vendored
32
src/cmd/vendor/github.com/google/pprof/internal/driver/testdata/pprof.heap_tags.traces
generated
vendored
@ -1,32 +0,0 @@
|
||||
Build ID: buildid
|
||||
comment
|
||||
Type: inuse_space
|
||||
-----------+-------------------------------------------------------
|
||||
key1: tag
|
||||
bytes: 100kB
|
||||
request: 100kB
|
||||
1000kB line1000
|
||||
line2001
|
||||
line2000
|
||||
line3002
|
||||
line3001
|
||||
line3000
|
||||
-----------+-------------------------------------------------------
|
||||
bytes: 200kB
|
||||
3.91MB line1000
|
||||
line3001
|
||||
line3000
|
||||
-----------+-------------------------------------------------------
|
||||
key1: tag
|
||||
bytes: 1.56MB
|
||||
request: 1.56MB
|
||||
62.50MB line2001
|
||||
line2000
|
||||
line3002
|
||||
line3000
|
||||
-----------+-------------------------------------------------------
|
||||
bytes: 400kB
|
||||
31.25MB line3002
|
||||
line3001
|
||||
line3000
|
||||
-----------+-------------------------------------------------------
|
@ -1,9 +0,0 @@
|
||||
digraph "testbinary" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "File: testbinary" [shape=box fontsize=16 label="File: testbinary\lType: cpu\lDuration: 10s, Total samples = 1.11s (11.10%)\lShowing nodes accounting for 1.11s, 100% of 1.11s total\l" tooltip="testbinary"] }
|
||||
N1 [label="package1\nobject\nfunction1\n1.10s (99.10%)" id="node1" fontsize=24 shape=box tooltip="path/to/package1.object.function1 (1.10s)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N2 [label="FooBar\nrun\n0.01s (0.9%)\nof 1.01s (90.99%)" id="node2" fontsize=10 shape=box tooltip="java.bar.foo.FooBar.run(java.lang.Runnable) (1.01s)" color="#b20400" fillcolor="#edd6d5"]
|
||||
N3 [label="Bar\nFoo\n0 of 1.10s (99.10%)" id="node3" fontsize=8 shape=box tooltip="(anonymous namespace)::Bar::Foo (1.10s)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N3 -> N1 [label=" 1.10s" weight=100 penwidth=5 color="#b20000" tooltip="(anonymous namespace)::Bar::Foo -> path/to/package1.object.function1 (1.10s)" labeltooltip="(anonymous namespace)::Bar::Foo -> path/to/package1.object.function1 (1.10s)"]
|
||||
N2 -> N3 [label=" 1s" weight=91 penwidth=5 color="#b20500" tooltip="java.bar.foo.FooBar.run(java.lang.Runnable) -> (anonymous namespace)::Bar::Foo (1s)" labeltooltip="java.bar.foo.FooBar.run(java.lang.Runnable) -> (anonymous namespace)::Bar::Foo (1s)"]
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
Showing nodes accounting for 1.11s, 100% of 1.11s total
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 99.10% 99.10% 1.10s 99.10% path/to/package1.object.function1
|
||||
0.01s 0.9% 100% 1.01s 90.99% java.bar.foo.FooBar.run(java.lang.Runnable)
|
||||
0 0% 100% 1.10s 99.10% (anonymous namespace)::Bar::Foo
|
@ -1,8 +0,0 @@
|
||||
Showing nodes accounting for 1.12s, 100% of 1.12s total
|
||||
Showing top 5 nodes out of 6
|
||||
flat flat% sum% cum cum%
|
||||
1.10s 98.21% 98.21% 1.10s 98.21% line1000
|
||||
0.01s 0.89% 99.11% 1.01s 90.18% line2001 (inline)
|
||||
0.01s 0.89% 100% 1.02s 91.07% line3002 (inline)
|
||||
0 0% 100% 1.01s 90.18% line2000
|
||||
0 0% 100% 1.12s 100% line3000
|
9
src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
generated
vendored
9
src/cmd/vendor/github.com/google/pprof/internal/driver/webui.go
generated
vendored
@ -179,11 +179,18 @@ func defaultWebServer(args *plugin.HTTPServerArgs) error {
|
||||
// https://github.com/google/pprof/pull/348
|
||||
mux := http.NewServeMux()
|
||||
mux.Handle("/ui/", http.StripPrefix("/ui", handler))
|
||||
mux.Handle("/", http.RedirectHandler("/ui/", http.StatusTemporaryRedirect))
|
||||
mux.Handle("/", redirectWithQuery("/ui"))
|
||||
s := &http.Server{Handler: mux}
|
||||
return s.Serve(ln)
|
||||
}
|
||||
|
||||
func redirectWithQuery(path string) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
pathWithQuery := &gourl.URL{Path: path, RawQuery: r.URL.RawQuery}
|
||||
http.Redirect(w, r, pathWithQuery.String(), http.StatusTemporaryRedirect)
|
||||
}
|
||||
}
|
||||
|
||||
func isLocalhost(host string) bool {
|
||||
for _, v := range []string{"localhost", "127.0.0.1", "[::1]", "::1"} {
|
||||
if host == v {
|
||||
|
285
src/cmd/vendor/github.com/google/pprof/internal/driver/webui_test.go
generated
vendored
285
src/cmd/vendor/github.com/google/pprof/internal/driver/webui_test.go
generated
vendored
@ -1,285 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package driver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/google/pprof/internal/plugin"
|
||||
"github.com/google/pprof/internal/proftest"
|
||||
"github.com/google/pprof/profile"
|
||||
)
|
||||
|
||||
func TestWebInterface(t *testing.T) {
|
||||
if runtime.GOOS == "nacl" || runtime.GOOS == "js" {
|
||||
t.Skip("test assumes tcp available")
|
||||
}
|
||||
|
||||
prof := makeFakeProfile()
|
||||
|
||||
// Custom http server creator
|
||||
var server *httptest.Server
|
||||
serverCreated := make(chan bool)
|
||||
creator := func(a *plugin.HTTPServerArgs) error {
|
||||
server = httptest.NewServer(http.HandlerFunc(
|
||||
func(w http.ResponseWriter, r *http.Request) {
|
||||
if h := a.Handlers[r.URL.Path]; h != nil {
|
||||
h.ServeHTTP(w, r)
|
||||
}
|
||||
}))
|
||||
serverCreated <- true
|
||||
return nil
|
||||
}
|
||||
|
||||
// Start server and wait for it to be initialized
|
||||
go serveWebInterface("unused:1234", prof, &plugin.Options{
|
||||
Obj: fakeObjTool{},
|
||||
UI: &proftest.TestUI{},
|
||||
HTTPServer: creator,
|
||||
})
|
||||
<-serverCreated
|
||||
defer server.Close()
|
||||
|
||||
haveDot := false
|
||||
if _, err := exec.LookPath("dot"); err == nil {
|
||||
haveDot = true
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
path string
|
||||
want []string
|
||||
needDot bool
|
||||
}
|
||||
testcases := []testCase{
|
||||
{"/", []string{"F1", "F2", "F3", "testbin", "cpu"}, true},
|
||||
{"/top", []string{`"Name":"F2","InlineLabel":"","Flat":200,"Cum":300,"FlatFormat":"200ms","CumFormat":"300ms"}`}, false},
|
||||
{"/source?f=" + url.QueryEscape("F[12]"),
|
||||
[]string{"F1", "F2", "300ms +line1"}, false},
|
||||
{"/peek?f=" + url.QueryEscape("F[12]"),
|
||||
[]string{"300ms.*F1", "200ms.*300ms.*F2"}, false},
|
||||
{"/disasm?f=" + url.QueryEscape("F[12]"),
|
||||
[]string{"f1:asm", "f2:asm"}, false},
|
||||
{"/flamegraph", []string{"File: testbin", "\"n\":\"root\"", "\"n\":\"F1\"", "var flamegraph = function", "function hierarchy"}, false},
|
||||
}
|
||||
for _, c := range testcases {
|
||||
if c.needDot && !haveDot {
|
||||
t.Log("skipping", c.path, "since dot (graphviz) does not seem to be installed")
|
||||
continue
|
||||
}
|
||||
|
||||
res, err := http.Get(server.URL + c.path)
|
||||
if err != nil {
|
||||
t.Error("could not fetch", c.path, err)
|
||||
continue
|
||||
}
|
||||
data, err := ioutil.ReadAll(res.Body)
|
||||
if err != nil {
|
||||
t.Error("could not read response", c.path, err)
|
||||
continue
|
||||
}
|
||||
result := string(data)
|
||||
for _, w := range c.want {
|
||||
if match, _ := regexp.MatchString(w, result); !match {
|
||||
t.Errorf("response for %s does not match "+
|
||||
"expected pattern '%s'; "+
|
||||
"actual result:\n%s", c.path, w, result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Also fetch all the test case URLs in parallel to test thread
|
||||
// safety when run under the race detector.
|
||||
var wg sync.WaitGroup
|
||||
for _, c := range testcases {
|
||||
if c.needDot && !haveDot {
|
||||
continue
|
||||
}
|
||||
path := server.URL + c.path
|
||||
for count := 0; count < 2; count++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
res, err := http.Get(path)
|
||||
if err != nil {
|
||||
t.Error("could not fetch", c.path, err)
|
||||
return
|
||||
}
|
||||
if _, err = ioutil.ReadAll(res.Body); err != nil {
|
||||
t.Error("could not read response", c.path, err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
// Implement fake object file support.
|
||||
|
||||
const addrBase = 0x1000
|
||||
const fakeSource = "testdata/file1000.src"
|
||||
|
||||
type fakeObj struct{}
|
||||
|
||||
func (f fakeObj) Close() error { return nil }
|
||||
func (f fakeObj) Name() string { return "testbin" }
|
||||
func (f fakeObj) Base() uint64 { return 0 }
|
||||
func (f fakeObj) BuildID() string { return "" }
|
||||
func (f fakeObj) SourceLine(addr uint64) ([]plugin.Frame, error) {
|
||||
return nil, fmt.Errorf("SourceLine unimplemented")
|
||||
}
|
||||
func (f fakeObj) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) {
|
||||
return []*plugin.Sym{
|
||||
{
|
||||
Name: []string{"F1"}, File: fakeSource,
|
||||
Start: addrBase, End: addrBase + 10,
|
||||
},
|
||||
{
|
||||
Name: []string{"F2"}, File: fakeSource,
|
||||
Start: addrBase + 10, End: addrBase + 20,
|
||||
},
|
||||
{
|
||||
Name: []string{"F3"}, File: fakeSource,
|
||||
Start: addrBase + 20, End: addrBase + 30,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
type fakeObjTool struct{}
|
||||
|
||||
func (obj fakeObjTool) Open(file string, start, limit, offset uint64) (plugin.ObjFile, error) {
|
||||
return fakeObj{}, nil
|
||||
}
|
||||
|
||||
func (obj fakeObjTool) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
|
||||
return []plugin.Inst{
|
||||
{Addr: addrBase + 0, Text: "f1:asm", Function: "F1"},
|
||||
{Addr: addrBase + 10, Text: "f2:asm", Function: "F2"},
|
||||
{Addr: addrBase + 20, Text: "d3:asm", Function: "F3"},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func makeFakeProfile() *profile.Profile {
|
||||
// Three functions: F1, F2, F3 with three lines, 11, 22, 33.
|
||||
funcs := []*profile.Function{
|
||||
{ID: 1, Name: "F1", Filename: fakeSource, StartLine: 3},
|
||||
{ID: 2, Name: "F2", Filename: fakeSource, StartLine: 5},
|
||||
{ID: 3, Name: "F3", Filename: fakeSource, StartLine: 7},
|
||||
}
|
||||
lines := []profile.Line{
|
||||
{Function: funcs[0], Line: 11},
|
||||
{Function: funcs[1], Line: 22},
|
||||
{Function: funcs[2], Line: 33},
|
||||
}
|
||||
mapping := []*profile.Mapping{
|
||||
{
|
||||
ID: 1,
|
||||
Start: addrBase,
|
||||
Limit: addrBase + 10,
|
||||
Offset: 0,
|
||||
File: "testbin",
|
||||
HasFunctions: true,
|
||||
HasFilenames: true,
|
||||
HasLineNumbers: true,
|
||||
},
|
||||
}
|
||||
|
||||
// Three interesting addresses: base+{10,20,30}
|
||||
locs := []*profile.Location{
|
||||
{ID: 1, Address: addrBase + 10, Line: lines[0:1], Mapping: mapping[0]},
|
||||
{ID: 2, Address: addrBase + 20, Line: lines[1:2], Mapping: mapping[0]},
|
||||
{ID: 3, Address: addrBase + 30, Line: lines[2:3], Mapping: mapping[0]},
|
||||
}
|
||||
|
||||
// Two stack traces.
|
||||
return &profile.Profile{
|
||||
PeriodType: &profile.ValueType{Type: "cpu", Unit: "milliseconds"},
|
||||
Period: 1,
|
||||
DurationNanos: 10e9,
|
||||
SampleType: []*profile.ValueType{
|
||||
{Type: "cpu", Unit: "milliseconds"},
|
||||
},
|
||||
Sample: []*profile.Sample{
|
||||
{
|
||||
Location: []*profile.Location{locs[2], locs[1], locs[0]},
|
||||
Value: []int64{100},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{locs[1], locs[0]},
|
||||
Value: []int64{200},
|
||||
},
|
||||
},
|
||||
Location: locs,
|
||||
Function: funcs,
|
||||
Mapping: mapping,
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHostAndPort(t *testing.T) {
|
||||
if runtime.GOOS == "nacl" || runtime.GOOS == "js" {
|
||||
t.Skip("test assumes tcp available")
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
hostport string
|
||||
wantHost string
|
||||
wantPort int
|
||||
wantRandomPort bool
|
||||
}
|
||||
|
||||
testCases := []testCase{
|
||||
{":", "localhost", 0, true},
|
||||
{":4681", "localhost", 4681, false},
|
||||
{"localhost:4681", "localhost", 4681, false},
|
||||
}
|
||||
for _, tc := range testCases {
|
||||
host, port, err := getHostAndPort(tc.hostport)
|
||||
if err != nil {
|
||||
t.Errorf("could not get host and port for %q: %v", tc.hostport, err)
|
||||
}
|
||||
if got, want := host, tc.wantHost; got != want {
|
||||
t.Errorf("for %s, got host %s, want %s", tc.hostport, got, want)
|
||||
continue
|
||||
}
|
||||
if !tc.wantRandomPort {
|
||||
if got, want := port, tc.wantPort; got != want {
|
||||
t.Errorf("for %s, got port %d, want %d", tc.hostport, got, want)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsLocalHost(t *testing.T) {
|
||||
for _, s := range []string{"localhost:10000", "[::1]:10000", "127.0.0.1:10000"} {
|
||||
host, _, err := net.SplitHostPort(s)
|
||||
if err != nil {
|
||||
t.Error("unexpected error when splitting", s)
|
||||
continue
|
||||
}
|
||||
if !isLocalhost(host) {
|
||||
t.Errorf("host %s from %s not considered local", host, s)
|
||||
}
|
||||
}
|
||||
}
|
102
src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go
generated
vendored
102
src/cmd/vendor/github.com/google/pprof/internal/elfexec/elfexec_test.go
generated
vendored
@ -1,102 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package elfexec
|
||||
|
||||
import (
|
||||
"debug/elf"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestGetBase(t *testing.T) {
|
||||
|
||||
fhExec := &elf.FileHeader{
|
||||
Type: elf.ET_EXEC,
|
||||
}
|
||||
fhRel := &elf.FileHeader{
|
||||
Type: elf.ET_REL,
|
||||
}
|
||||
fhDyn := &elf.FileHeader{
|
||||
Type: elf.ET_DYN,
|
||||
}
|
||||
lsOffset := &elf.ProgHeader{
|
||||
Vaddr: 0x400000,
|
||||
Off: 0x200000,
|
||||
}
|
||||
kernelHeader := &elf.ProgHeader{
|
||||
Vaddr: 0xffffffff81000000,
|
||||
}
|
||||
kernelAslrHeader := &elf.ProgHeader{
|
||||
Vaddr: 0xffffffff80200000,
|
||||
Off: 0x1000,
|
||||
}
|
||||
ppc64KernelHeader := &elf.ProgHeader{
|
||||
Vaddr: 0xc000000000000000,
|
||||
}
|
||||
|
||||
testcases := []struct {
|
||||
label string
|
||||
fh *elf.FileHeader
|
||||
loadSegment *elf.ProgHeader
|
||||
stextOffset *uint64
|
||||
start, limit, offset uint64
|
||||
want uint64
|
||||
wanterr bool
|
||||
}{
|
||||
{"exec", fhExec, nil, nil, 0x400000, 0, 0, 0, false},
|
||||
{"exec offset", fhExec, lsOffset, nil, 0x400000, 0x800000, 0, 0x200000, false},
|
||||
{"exec offset 2", fhExec, lsOffset, nil, 0x200000, 0x600000, 0, 0, false},
|
||||
{"exec nomap", fhExec, nil, nil, 0, 0, 0, 0, false},
|
||||
{"exec kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0xffffffff82000198, 0xffffffff83000198, 0, 0x1000000, false},
|
||||
{"exec kernel", fhExec, kernelHeader, uint64p(0xffffffff810002b8), 0xffffffff81000000, 0xffffffffa0000000, 0x0, 0x0, false},
|
||||
{"exec kernel ASLR", fhExec, kernelHeader, uint64p(0xffffffff810002b8), 0xffffffff81000000, 0xffffffffa0000000, 0xffffffff81000000, 0x0, false},
|
||||
// TODO(aalexand): Figure out where this test case exactly comes from and
|
||||
// whether it's still relevant.
|
||||
{"exec kernel ASLR 2", fhExec, kernelAslrHeader, nil, 0xffffffff83e00000, 0xfffffffffc3fffff, 0x3c00000, 0x3c00000, false},
|
||||
{"exec PPC64 kernel", fhExec, ppc64KernelHeader, uint64p(0xc000000000000000), 0xc000000000000000, 0xd00000001a730000, 0x0, 0x0, false},
|
||||
{"exec chromeos kernel", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10197, 0, 0x7efffe68, false},
|
||||
{"exec chromeos kernel 2", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0, 0x10198, 0, 0x7efffe68, false},
|
||||
{"exec chromeos kernel 3", fhExec, kernelHeader, uint64p(0xffffffff81000198), 0x198, 0x100000, 0, 0x7f000000, false},
|
||||
{"exec chromeos kernel 4", fhExec, kernelHeader, uint64p(0xffffffff81200198), 0x198, 0x100000, 0, 0x7ee00000, false},
|
||||
{"exec chromeos kernel unremapped", fhExec, kernelHeader, uint64p(0xffffffff810001c8), 0xffffffff834001c8, 0xffffffffc0000000, 0xffffffff834001c8, 0x2400000, false},
|
||||
{"dyn", fhDyn, nil, nil, 0x200000, 0x300000, 0, 0x200000, false},
|
||||
{"dyn map", fhDyn, lsOffset, nil, 0x0, 0x300000, 0, 0xFFFFFFFFFFE00000, false},
|
||||
{"dyn nomap", fhDyn, nil, nil, 0x0, 0x0, 0, 0, false},
|
||||
{"dyn map+offset", fhDyn, lsOffset, nil, 0x900000, 0xa00000, 0x200000, 0x500000, false},
|
||||
{"rel", fhRel, nil, nil, 0x2000000, 0x3000000, 0, 0x2000000, false},
|
||||
{"rel nomap", fhRel, nil, nil, 0x0, ^uint64(0), 0, 0, false},
|
||||
{"rel offset", fhRel, nil, nil, 0x100000, 0x200000, 0x1, 0, true},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
base, err := GetBase(tc.fh, tc.loadSegment, tc.stextOffset, tc.start, tc.limit, tc.offset)
|
||||
if err != nil {
|
||||
if !tc.wanterr {
|
||||
t.Errorf("%s: want no error, got %v", tc.label, err)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if tc.wanterr {
|
||||
t.Errorf("%s: want error, got nil", tc.label)
|
||||
continue
|
||||
}
|
||||
if base != tc.want {
|
||||
t.Errorf("%s: want 0x%x, got 0x%x", tc.label, tc.want, base)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func uint64p(n uint64) *uint64 {
|
||||
return &n
|
||||
}
|
335
src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph_test.go
generated
vendored
335
src/cmd/vendor/github.com/google/pprof/internal/graph/dotgraph_test.go
generated
vendored
@ -1,335 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package graph
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/pprof/internal/proftest"
|
||||
)
|
||||
|
||||
var updateFlag = flag.Bool("update", false, "Update the golden files")
|
||||
|
||||
func TestComposeWithStandardGraph(t *testing.T) {
|
||||
g := baseGraph()
|
||||
a, c := baseAttrsAndConfig()
|
||||
|
||||
var buf bytes.Buffer
|
||||
ComposeDot(&buf, g, a, c)
|
||||
|
||||
compareGraphs(t, buf.Bytes(), "compose1.dot")
|
||||
}
|
||||
|
||||
func TestComposeWithNodeAttributesAndZeroFlat(t *testing.T) {
|
||||
g := baseGraph()
|
||||
a, c := baseAttrsAndConfig()
|
||||
|
||||
// Set NodeAttributes for Node 1.
|
||||
a.Nodes[g.Nodes[0]] = &DotNodeAttributes{
|
||||
Shape: "folder",
|
||||
Bold: true,
|
||||
Peripheries: 2,
|
||||
URL: "www.google.com",
|
||||
Formatter: func(ni *NodeInfo) string {
|
||||
return strings.ToUpper(ni.Name)
|
||||
},
|
||||
}
|
||||
|
||||
// Set Flat value to zero on Node 2.
|
||||
g.Nodes[1].Flat = 0
|
||||
|
||||
var buf bytes.Buffer
|
||||
ComposeDot(&buf, g, a, c)
|
||||
|
||||
compareGraphs(t, buf.Bytes(), "compose2.dot")
|
||||
}
|
||||
|
||||
func TestComposeWithTagsAndResidualEdge(t *testing.T) {
|
||||
g := baseGraph()
|
||||
a, c := baseAttrsAndConfig()
|
||||
|
||||
// Add tags to Node 1.
|
||||
g.Nodes[0].LabelTags["a"] = &Tag{
|
||||
Name: "tag1",
|
||||
Cum: 10,
|
||||
Flat: 10,
|
||||
}
|
||||
g.Nodes[0].NumericTags[""] = TagMap{
|
||||
"b": &Tag{
|
||||
Name: "tag2",
|
||||
Cum: 20,
|
||||
Flat: 20,
|
||||
Unit: "ms",
|
||||
},
|
||||
}
|
||||
|
||||
// Set edge to be Residual.
|
||||
g.Nodes[0].Out[g.Nodes[1]].Residual = true
|
||||
|
||||
var buf bytes.Buffer
|
||||
ComposeDot(&buf, g, a, c)
|
||||
|
||||
compareGraphs(t, buf.Bytes(), "compose3.dot")
|
||||
}
|
||||
|
||||
func TestComposeWithNestedTags(t *testing.T) {
|
||||
g := baseGraph()
|
||||
a, c := baseAttrsAndConfig()
|
||||
|
||||
// Add tags to Node 1.
|
||||
g.Nodes[0].LabelTags["tag1"] = &Tag{
|
||||
Name: "tag1",
|
||||
Cum: 10,
|
||||
Flat: 10,
|
||||
}
|
||||
g.Nodes[0].NumericTags["tag1"] = TagMap{
|
||||
"tag2": &Tag{
|
||||
Name: "tag2",
|
||||
Cum: 20,
|
||||
Flat: 20,
|
||||
Unit: "ms",
|
||||
},
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
ComposeDot(&buf, g, a, c)
|
||||
|
||||
compareGraphs(t, buf.Bytes(), "compose5.dot")
|
||||
}
|
||||
|
||||
func TestComposeWithEmptyGraph(t *testing.T) {
|
||||
g := &Graph{}
|
||||
a, c := baseAttrsAndConfig()
|
||||
|
||||
var buf bytes.Buffer
|
||||
ComposeDot(&buf, g, a, c)
|
||||
|
||||
compareGraphs(t, buf.Bytes(), "compose4.dot")
|
||||
}
|
||||
|
||||
func TestComposeWithStandardGraphAndURL(t *testing.T) {
|
||||
g := baseGraph()
|
||||
a, c := baseAttrsAndConfig()
|
||||
c.LegendURL = "http://example.com"
|
||||
|
||||
var buf bytes.Buffer
|
||||
ComposeDot(&buf, g, a, c)
|
||||
|
||||
compareGraphs(t, buf.Bytes(), "compose6.dot")
|
||||
}
|
||||
|
||||
func baseGraph() *Graph {
|
||||
src := &Node{
|
||||
Info: NodeInfo{Name: "src"},
|
||||
Flat: 10,
|
||||
Cum: 25,
|
||||
In: make(EdgeMap),
|
||||
Out: make(EdgeMap),
|
||||
LabelTags: make(TagMap),
|
||||
NumericTags: make(map[string]TagMap),
|
||||
}
|
||||
dest := &Node{
|
||||
Info: NodeInfo{Name: "dest"},
|
||||
Flat: 15,
|
||||
Cum: 25,
|
||||
In: make(EdgeMap),
|
||||
Out: make(EdgeMap),
|
||||
LabelTags: make(TagMap),
|
||||
NumericTags: make(map[string]TagMap),
|
||||
}
|
||||
edge := &Edge{
|
||||
Src: src,
|
||||
Dest: dest,
|
||||
Weight: 10,
|
||||
}
|
||||
src.Out[dest] = edge
|
||||
src.In[src] = edge
|
||||
return &Graph{
|
||||
Nodes: Nodes{
|
||||
src,
|
||||
dest,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func baseAttrsAndConfig() (*DotAttributes, *DotConfig) {
|
||||
a := &DotAttributes{
|
||||
Nodes: make(map[*Node]*DotNodeAttributes),
|
||||
}
|
||||
c := &DotConfig{
|
||||
Title: "testtitle",
|
||||
Labels: []string{"label1", "label2"},
|
||||
Total: 100,
|
||||
FormatValue: func(v int64) string {
|
||||
return strconv.FormatInt(v, 10)
|
||||
},
|
||||
}
|
||||
return a, c
|
||||
}
|
||||
|
||||
func compareGraphs(t *testing.T, got []byte, wantFile string) {
|
||||
wantFile = filepath.Join("testdata", wantFile)
|
||||
want, err := ioutil.ReadFile(wantFile)
|
||||
if err != nil {
|
||||
t.Fatalf("error reading test file %s: %v", wantFile, err)
|
||||
}
|
||||
|
||||
if string(got) != string(want) {
|
||||
d, err := proftest.Diff(got, want)
|
||||
if err != nil {
|
||||
t.Fatalf("error finding diff: %v", err)
|
||||
}
|
||||
t.Errorf("Compose incorrectly wrote %s", string(d))
|
||||
if *updateFlag {
|
||||
err := ioutil.WriteFile(wantFile, got, 0644)
|
||||
if err != nil {
|
||||
t.Errorf("failed to update the golden file %q: %v", wantFile, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestNodeletCountCapping(t *testing.T) {
|
||||
labelTags := make(TagMap)
|
||||
for i := 0; i < 10; i++ {
|
||||
name := fmt.Sprintf("tag-%d", i)
|
||||
labelTags[name] = &Tag{
|
||||
Name: name,
|
||||
Flat: 10,
|
||||
Cum: 10,
|
||||
}
|
||||
}
|
||||
numTags := make(TagMap)
|
||||
for i := 0; i < 10; i++ {
|
||||
name := fmt.Sprintf("num-tag-%d", i)
|
||||
numTags[name] = &Tag{
|
||||
Name: name,
|
||||
Unit: "mb",
|
||||
Value: 16,
|
||||
Flat: 10,
|
||||
Cum: 10,
|
||||
}
|
||||
}
|
||||
node1 := &Node{
|
||||
Info: NodeInfo{Name: "node1-with-tags"},
|
||||
Flat: 10,
|
||||
Cum: 10,
|
||||
NumericTags: map[string]TagMap{"": numTags},
|
||||
LabelTags: labelTags,
|
||||
}
|
||||
node2 := &Node{
|
||||
Info: NodeInfo{Name: "node2"},
|
||||
Flat: 15,
|
||||
Cum: 15,
|
||||
}
|
||||
node3 := &Node{
|
||||
Info: NodeInfo{Name: "node3"},
|
||||
Flat: 15,
|
||||
Cum: 15,
|
||||
}
|
||||
g := &Graph{
|
||||
Nodes: Nodes{
|
||||
node1,
|
||||
node2,
|
||||
node3,
|
||||
},
|
||||
}
|
||||
for n := 1; n <= 3; n++ {
|
||||
input := maxNodelets + n
|
||||
if got, want := len(g.SelectTopNodes(input, true)), n; got != want {
|
||||
t.Errorf("SelectTopNodes(%d): got %d nodes, want %d", input, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMultilinePrintableName(t *testing.T) {
|
||||
ni := &NodeInfo{
|
||||
Name: "test1.test2::test3",
|
||||
File: "src/file.cc",
|
||||
Address: 123,
|
||||
Lineno: 999,
|
||||
}
|
||||
|
||||
want := fmt.Sprintf(`%016x\ntest1\ntest2\ntest3\nfile.cc:999\n`, 123)
|
||||
if got := multilinePrintableName(ni); got != want {
|
||||
t.Errorf("multilinePrintableName(%#v) == %q, want %q", ni, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTagCollapse(t *testing.T) {
|
||||
|
||||
makeTag := func(name, unit string, value, flat, cum int64) *Tag {
|
||||
return &Tag{name, unit, value, flat, 0, cum, 0}
|
||||
}
|
||||
|
||||
tagSource := []*Tag{
|
||||
makeTag("12mb", "mb", 12, 100, 100),
|
||||
makeTag("1kb", "kb", 1, 1, 1),
|
||||
makeTag("1mb", "mb", 1, 1000, 1000),
|
||||
makeTag("2048mb", "mb", 2048, 1000, 1000),
|
||||
makeTag("1b", "b", 1, 100, 100),
|
||||
makeTag("2b", "b", 2, 100, 100),
|
||||
makeTag("7b", "b", 7, 100, 100),
|
||||
}
|
||||
|
||||
tagWant := [][]*Tag{
|
||||
{
|
||||
makeTag("1B..2GB", "", 0, 2401, 2401),
|
||||
},
|
||||
{
|
||||
makeTag("2GB", "", 0, 1000, 1000),
|
||||
makeTag("1B..12MB", "", 0, 1401, 1401),
|
||||
},
|
||||
{
|
||||
makeTag("2GB", "", 0, 1000, 1000),
|
||||
makeTag("12MB", "", 0, 100, 100),
|
||||
makeTag("1B..1MB", "", 0, 1301, 1301),
|
||||
},
|
||||
{
|
||||
makeTag("2GB", "", 0, 1000, 1000),
|
||||
makeTag("1MB", "", 0, 1000, 1000),
|
||||
makeTag("2B..1kB", "", 0, 201, 201),
|
||||
makeTag("1B", "", 0, 100, 100),
|
||||
makeTag("12MB", "", 0, 100, 100),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tagWant {
|
||||
var got, want []*Tag
|
||||
b := builder{nil, &DotAttributes{}, &DotConfig{}}
|
||||
got = b.collapsedTags(tagSource, len(tc), true)
|
||||
want = SortTags(tc, true)
|
||||
|
||||
if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("collapse to %d, got:\n%v\nwant:\n%v", len(tc), tagString(got), tagString(want))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func tagString(t []*Tag) string {
|
||||
var ret []string
|
||||
for _, s := range t {
|
||||
ret = append(ret, fmt.Sprintln(s))
|
||||
}
|
||||
return strings.Join(ret, ":")
|
||||
}
|
2
src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go
generated
vendored
2
src/cmd/vendor/github.com/google/pprof/internal/graph/graph.go
generated
vendored
@ -28,7 +28,7 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
javaRegExp = regexp.MustCompile(`^(?:[a-z]\w*\.)*([A-Z][\w\$]*\.(?:<init>|[a-z]\w*(?:\$\d+)?))(?:(?:\()|$)`)
|
||||
javaRegExp = regexp.MustCompile(`^(?:[a-z]\w*\.)*([A-Z][\w\$]*\.(?:<init>|[a-z][\w\$]*(?:\$\d+)?))(?:(?:\()|$)`)
|
||||
goRegExp = regexp.MustCompile(`^(?:[\w\-\.]+\/)+(.+)`)
|
||||
cppRegExp = regexp.MustCompile(`^(?:(?:\(anonymous namespace\)::)(\w+$))|(?:(?:\(anonymous namespace\)::)?(?:[_a-zA-Z]\w*\::|)*(_*[A-Z]\w*::~?[_a-zA-Z]\w*)$)`)
|
||||
)
|
||||
|
471
src/cmd/vendor/github.com/google/pprof/internal/graph/graph_test.go
generated
vendored
471
src/cmd/vendor/github.com/google/pprof/internal/graph/graph_test.go
generated
vendored
@ -1,471 +0,0 @@
|
||||
package graph
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/pprof/profile"
|
||||
)
|
||||
|
||||
func edgeDebugString(edge *Edge) string {
|
||||
debug := ""
|
||||
debug += fmt.Sprintf("\t\tSrc: %p\n", edge.Src)
|
||||
debug += fmt.Sprintf("\t\tDest: %p\n", edge.Dest)
|
||||
debug += fmt.Sprintf("\t\tWeight: %d\n", edge.Weight)
|
||||
debug += fmt.Sprintf("\t\tResidual: %t\n", edge.Residual)
|
||||
debug += fmt.Sprintf("\t\tInline: %t\n", edge.Inline)
|
||||
return debug
|
||||
}
|
||||
|
||||
func edgeMapsDebugString(in, out EdgeMap) string {
|
||||
debug := ""
|
||||
debug += "In Edges:\n"
|
||||
for parent, edge := range in {
|
||||
debug += fmt.Sprintf("\tParent: %p\n", parent)
|
||||
debug += edgeDebugString(edge)
|
||||
}
|
||||
debug += "Out Edges:\n"
|
||||
for child, edge := range out {
|
||||
debug += fmt.Sprintf("\tChild: %p\n", child)
|
||||
debug += edgeDebugString(edge)
|
||||
}
|
||||
return debug
|
||||
}
|
||||
|
||||
func graphDebugString(graph *Graph) string {
|
||||
debug := ""
|
||||
for i, node := range graph.Nodes {
|
||||
debug += fmt.Sprintf("Node %d: %p\n", i, node)
|
||||
}
|
||||
|
||||
for i, node := range graph.Nodes {
|
||||
debug += "\n"
|
||||
debug += fmt.Sprintf("=== Node %d: %p ===\n", i, node)
|
||||
debug += edgeMapsDebugString(node.In, node.Out)
|
||||
}
|
||||
return debug
|
||||
}
|
||||
|
||||
func expectedNodesDebugString(expected []expectedNode) string {
|
||||
debug := ""
|
||||
for i, node := range expected {
|
||||
debug += fmt.Sprintf("Node %d: %p\n", i, node.node)
|
||||
}
|
||||
|
||||
for i, node := range expected {
|
||||
debug += "\n"
|
||||
debug += fmt.Sprintf("=== Node %d: %p ===\n", i, node.node)
|
||||
debug += edgeMapsDebugString(node.in, node.out)
|
||||
}
|
||||
return debug
|
||||
}
|
||||
|
||||
// edgeMapsEqual checks if all the edges in this equal all the edges in that.
|
||||
func edgeMapsEqual(this, that EdgeMap) bool {
|
||||
if len(this) != len(that) {
|
||||
return false
|
||||
}
|
||||
for node, thisEdge := range this {
|
||||
if *thisEdge != *that[node] {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// nodesEqual checks if node is equal to expected.
|
||||
func nodesEqual(node *Node, expected expectedNode) bool {
|
||||
return node == expected.node && edgeMapsEqual(node.In, expected.in) &&
|
||||
edgeMapsEqual(node.Out, expected.out)
|
||||
}
|
||||
|
||||
// graphsEqual checks if graph is equivalent to the graph templated by expected.
|
||||
func graphsEqual(graph *Graph, expected []expectedNode) bool {
|
||||
if len(graph.Nodes) != len(expected) {
|
||||
return false
|
||||
}
|
||||
expectedSet := make(map[*Node]expectedNode)
|
||||
for i := range expected {
|
||||
expectedSet[expected[i].node] = expected[i]
|
||||
}
|
||||
|
||||
for _, node := range graph.Nodes {
|
||||
expectedNode, found := expectedSet[node]
|
||||
if !found || !nodesEqual(node, expectedNode) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type expectedNode struct {
|
||||
node *Node
|
||||
in, out EdgeMap
|
||||
}
|
||||
|
||||
type trimTreeTestcase struct {
|
||||
initial *Graph
|
||||
expected []expectedNode
|
||||
keep NodePtrSet
|
||||
}
|
||||
|
||||
// makeExpectedEdgeResidual makes the edge from parent to child residual.
|
||||
func makeExpectedEdgeResidual(parent, child expectedNode) {
|
||||
parent.out[child.node].Residual = true
|
||||
child.in[parent.node].Residual = true
|
||||
}
|
||||
|
||||
func makeEdgeInline(edgeMap EdgeMap, node *Node) {
|
||||
edgeMap[node].Inline = true
|
||||
}
|
||||
|
||||
func setEdgeWeight(edgeMap EdgeMap, node *Node, weight int64) {
|
||||
edgeMap[node].Weight = weight
|
||||
}
|
||||
|
||||
// createEdges creates directed edges from the parent to each of the children.
|
||||
func createEdges(parent *Node, children ...*Node) {
|
||||
for _, child := range children {
|
||||
edge := &Edge{
|
||||
Src: parent,
|
||||
Dest: child,
|
||||
}
|
||||
parent.Out[child] = edge
|
||||
child.In[parent] = edge
|
||||
}
|
||||
}
|
||||
|
||||
// createEmptyNode creates a node without any edges.
|
||||
func createEmptyNode() *Node {
|
||||
return &Node{
|
||||
In: make(EdgeMap),
|
||||
Out: make(EdgeMap),
|
||||
}
|
||||
}
|
||||
|
||||
// createExpectedNodes creates a slice of expectedNodes from nodes.
|
||||
func createExpectedNodes(nodes ...*Node) ([]expectedNode, NodePtrSet) {
|
||||
expected := make([]expectedNode, len(nodes))
|
||||
keep := make(NodePtrSet, len(nodes))
|
||||
|
||||
for i, node := range nodes {
|
||||
expected[i] = expectedNode{
|
||||
node: node,
|
||||
in: make(EdgeMap),
|
||||
out: make(EdgeMap),
|
||||
}
|
||||
keep[node] = true
|
||||
}
|
||||
|
||||
return expected, keep
|
||||
}
|
||||
|
||||
// createExpectedEdges creates directed edges from the parent to each of the
|
||||
// children.
|
||||
func createExpectedEdges(parent expectedNode, children ...expectedNode) {
|
||||
for _, child := range children {
|
||||
edge := &Edge{
|
||||
Src: parent.node,
|
||||
Dest: child.node,
|
||||
}
|
||||
parent.out[child.node] = edge
|
||||
child.in[parent.node] = edge
|
||||
}
|
||||
}
|
||||
|
||||
// createTestCase1 creates a test case that initially looks like:
|
||||
// 0
|
||||
// |(5)
|
||||
// 1
|
||||
// (3)/ \(4)
|
||||
// 2 3.
|
||||
//
|
||||
// After keeping 0, 2, and 3, it expects the graph:
|
||||
// 0
|
||||
// (3)/ \(4)
|
||||
// 2 3.
|
||||
func createTestCase1() trimTreeTestcase {
|
||||
// Create initial graph
|
||||
graph := &Graph{make(Nodes, 4)}
|
||||
nodes := graph.Nodes
|
||||
for i := range nodes {
|
||||
nodes[i] = createEmptyNode()
|
||||
}
|
||||
createEdges(nodes[0], nodes[1])
|
||||
createEdges(nodes[1], nodes[2], nodes[3])
|
||||
makeEdgeInline(nodes[0].Out, nodes[1])
|
||||
makeEdgeInline(nodes[1].Out, nodes[2])
|
||||
setEdgeWeight(nodes[0].Out, nodes[1], 5)
|
||||
setEdgeWeight(nodes[1].Out, nodes[2], 3)
|
||||
setEdgeWeight(nodes[1].Out, nodes[3], 4)
|
||||
|
||||
// Create expected graph
|
||||
expected, keep := createExpectedNodes(nodes[0], nodes[2], nodes[3])
|
||||
createExpectedEdges(expected[0], expected[1], expected[2])
|
||||
makeEdgeInline(expected[0].out, expected[1].node)
|
||||
makeExpectedEdgeResidual(expected[0], expected[1])
|
||||
makeExpectedEdgeResidual(expected[0], expected[2])
|
||||
setEdgeWeight(expected[0].out, expected[1].node, 3)
|
||||
setEdgeWeight(expected[0].out, expected[2].node, 4)
|
||||
return trimTreeTestcase{
|
||||
initial: graph,
|
||||
expected: expected,
|
||||
keep: keep,
|
||||
}
|
||||
}
|
||||
|
||||
// createTestCase2 creates a test case that initially looks like:
|
||||
// 3
|
||||
// | (12)
|
||||
// 1
|
||||
// | (8)
|
||||
// 2
|
||||
// | (15)
|
||||
// 0
|
||||
// | (10)
|
||||
// 4.
|
||||
//
|
||||
// After keeping 3 and 4, it expects the graph:
|
||||
// 3
|
||||
// | (10)
|
||||
// 4.
|
||||
func createTestCase2() trimTreeTestcase {
|
||||
// Create initial graph
|
||||
graph := &Graph{make(Nodes, 5)}
|
||||
nodes := graph.Nodes
|
||||
for i := range nodes {
|
||||
nodes[i] = createEmptyNode()
|
||||
}
|
||||
createEdges(nodes[3], nodes[1])
|
||||
createEdges(nodes[1], nodes[2])
|
||||
createEdges(nodes[2], nodes[0])
|
||||
createEdges(nodes[0], nodes[4])
|
||||
setEdgeWeight(nodes[3].Out, nodes[1], 12)
|
||||
setEdgeWeight(nodes[1].Out, nodes[2], 8)
|
||||
setEdgeWeight(nodes[2].Out, nodes[0], 15)
|
||||
setEdgeWeight(nodes[0].Out, nodes[4], 10)
|
||||
|
||||
// Create expected graph
|
||||
expected, keep := createExpectedNodes(nodes[3], nodes[4])
|
||||
createExpectedEdges(expected[0], expected[1])
|
||||
makeExpectedEdgeResidual(expected[0], expected[1])
|
||||
setEdgeWeight(expected[0].out, expected[1].node, 10)
|
||||
return trimTreeTestcase{
|
||||
initial: graph,
|
||||
expected: expected,
|
||||
keep: keep,
|
||||
}
|
||||
}
|
||||
|
||||
// createTestCase3 creates an initially empty graph and expects an empty graph
|
||||
// after trimming.
|
||||
func createTestCase3() trimTreeTestcase {
|
||||
graph := &Graph{make(Nodes, 0)}
|
||||
expected, keep := createExpectedNodes()
|
||||
return trimTreeTestcase{
|
||||
initial: graph,
|
||||
expected: expected,
|
||||
keep: keep,
|
||||
}
|
||||
}
|
||||
|
||||
// createTestCase4 creates a test case that initially looks like:
|
||||
// 0.
|
||||
//
|
||||
// After keeping 0, it expects the graph:
|
||||
// 0.
|
||||
func createTestCase4() trimTreeTestcase {
|
||||
graph := &Graph{make(Nodes, 1)}
|
||||
nodes := graph.Nodes
|
||||
for i := range nodes {
|
||||
nodes[i] = createEmptyNode()
|
||||
}
|
||||
expected, keep := createExpectedNodes(nodes[0])
|
||||
return trimTreeTestcase{
|
||||
initial: graph,
|
||||
expected: expected,
|
||||
keep: keep,
|
||||
}
|
||||
}
|
||||
|
||||
func createTrimTreeTestCases() []trimTreeTestcase {
|
||||
caseGenerators := []func() trimTreeTestcase{
|
||||
createTestCase1,
|
||||
createTestCase2,
|
||||
createTestCase3,
|
||||
createTestCase4,
|
||||
}
|
||||
cases := make([]trimTreeTestcase, len(caseGenerators))
|
||||
for i, gen := range caseGenerators {
|
||||
cases[i] = gen()
|
||||
}
|
||||
return cases
|
||||
}
|
||||
|
||||
func TestTrimTree(t *testing.T) {
|
||||
tests := createTrimTreeTestCases()
|
||||
for _, test := range tests {
|
||||
graph := test.initial
|
||||
graph.TrimTree(test.keep)
|
||||
if !graphsEqual(graph, test.expected) {
|
||||
t.Fatalf("Graphs do not match.\nExpected: %s\nFound: %s\n",
|
||||
expectedNodesDebugString(test.expected),
|
||||
graphDebugString(graph))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func nodeTestProfile() *profile.Profile {
|
||||
mappings := []*profile.Mapping{
|
||||
{
|
||||
ID: 1,
|
||||
File: "symbolized_binary",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
File: "unsymbolized_library_1",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
File: "unsymbolized_library_2",
|
||||
},
|
||||
}
|
||||
functions := []*profile.Function{
|
||||
{ID: 1, Name: "symname"},
|
||||
{ID: 2},
|
||||
}
|
||||
locations := []*profile.Location{
|
||||
{
|
||||
ID: 1,
|
||||
Mapping: mappings[0],
|
||||
Line: []profile.Line{
|
||||
{Function: functions[0]},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Mapping: mappings[1],
|
||||
Line: []profile.Line{
|
||||
{Function: functions[1]},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Mapping: mappings[2],
|
||||
},
|
||||
}
|
||||
return &profile.Profile{
|
||||
PeriodType: &profile.ValueType{Type: "cpu", Unit: "milliseconds"},
|
||||
SampleType: []*profile.ValueType{
|
||||
{Type: "type", Unit: "unit"},
|
||||
},
|
||||
Sample: []*profile.Sample{
|
||||
{
|
||||
Location: []*profile.Location{locations[0]},
|
||||
Value: []int64{1},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{locations[1]},
|
||||
Value: []int64{1},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{locations[2]},
|
||||
Value: []int64{1},
|
||||
},
|
||||
},
|
||||
Location: locations,
|
||||
Function: functions,
|
||||
Mapping: mappings,
|
||||
}
|
||||
}
|
||||
|
||||
// Check that nodes are properly created for a simple profile.
|
||||
func TestCreateNodes(t *testing.T) {
|
||||
testProfile := nodeTestProfile()
|
||||
wantNodeSet := NodeSet{
|
||||
{Name: "symname"}: true,
|
||||
{Objfile: "unsymbolized_library_1"}: true,
|
||||
{Objfile: "unsymbolized_library_2"}: true,
|
||||
}
|
||||
|
||||
nodes, _ := CreateNodes(testProfile, &Options{})
|
||||
if len(nodes) != len(wantNodeSet) {
|
||||
t.Errorf("got %d nodes, want %d", len(nodes), len(wantNodeSet))
|
||||
}
|
||||
for _, node := range nodes {
|
||||
if !wantNodeSet[node.Info] {
|
||||
t.Errorf("unexpected node %v", node.Info)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestShortenFunctionName(t *testing.T) {
|
||||
type testCase struct {
|
||||
name string
|
||||
want string
|
||||
}
|
||||
testcases := []testCase{
|
||||
{
|
||||
"root",
|
||||
"root",
|
||||
},
|
||||
{
|
||||
"syscall.Syscall",
|
||||
"syscall.Syscall",
|
||||
},
|
||||
{
|
||||
"net/http.(*conn).serve",
|
||||
"http.(*conn).serve",
|
||||
},
|
||||
{
|
||||
"github.com/blahBlah/foo.Foo",
|
||||
"foo.Foo",
|
||||
},
|
||||
{
|
||||
"github.com/BlahBlah/foo.Foo",
|
||||
"foo.Foo",
|
||||
},
|
||||
{
|
||||
"github.com/blah-blah/foo_bar.(*FooBar).Foo",
|
||||
"foo_bar.(*FooBar).Foo",
|
||||
},
|
||||
{
|
||||
"encoding/json.(*structEncoder).(encoding/json.encode)-fm",
|
||||
"json.(*structEncoder).(encoding/json.encode)-fm",
|
||||
},
|
||||
{
|
||||
"github.com/blah/blah/vendor/gopkg.in/redis.v3.(*baseClient).(github.com/blah/blah/vendor/gopkg.in/redis.v3.process)-fm",
|
||||
"redis.v3.(*baseClient).(github.com/blah/blah/vendor/gopkg.in/redis.v3.process)-fm",
|
||||
},
|
||||
{
|
||||
"java.util.concurrent.ThreadPoolExecutor$Worker.run",
|
||||
"ThreadPoolExecutor$Worker.run",
|
||||
},
|
||||
{
|
||||
"java.bar.foo.FooBar.run(java.lang.Runnable)",
|
||||
"FooBar.run",
|
||||
},
|
||||
{
|
||||
"(anonymous namespace)::Bar::Foo",
|
||||
"Bar::Foo",
|
||||
},
|
||||
{
|
||||
"(anonymous namespace)::foo",
|
||||
"foo",
|
||||
},
|
||||
{
|
||||
"foo_bar::Foo::bar",
|
||||
"Foo::bar",
|
||||
},
|
||||
{
|
||||
"foo",
|
||||
"foo",
|
||||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
name := ShortenFunctionName(tc.name)
|
||||
if got, want := name, tc.want; got != want {
|
||||
t.Errorf("ShortenFunctionName(%q) = %q, want %q", tc.name, got, want)
|
||||
}
|
||||
}
|
||||
}
|
7
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose1.dot
generated
vendored
7
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose1.dot
generated
vendored
@ -1,7 +0,0 @@
|
||||
digraph "testtitle" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
|
||||
N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" id="node2" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src -> dest (10)" labeltooltip="src -> dest (10)"]
|
||||
}
|
7
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose2.dot
generated
vendored
7
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose2.dot
generated
vendored
@ -1,7 +0,0 @@
|
||||
digraph "testtitle" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
|
||||
N1 [label="SRC10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=24 shape=folder tooltip="src (25)" color="#b23c00" fillcolor="#edddd5" style="bold,filled" peripheries=2 URL="www.google.com" target="_blank"]
|
||||
N2 [label="dest\n0 of 25 (25.00%)" id="node2" fontsize=8 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src -> dest (10)" labeltooltip="src -> dest (10)"]
|
||||
}
|
11
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose3.dot
generated
vendored
11
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose3.dot
generated
vendored
@ -1,11 +0,0 @@
|
||||
digraph "testtitle" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
|
||||
N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N1_0 [label = "tag1" id="N1_0" fontsize=8 shape=box3d tooltip="10"]
|
||||
N1 -> N1_0 [label=" 10" weight=100 tooltip="10" labeltooltip="10"]
|
||||
NN1_0 [label = "tag2" id="NN1_0" fontsize=8 shape=box3d tooltip="20"]
|
||||
N1 -> NN1_0 [label=" 20" weight=100 tooltip="20" labeltooltip="20"]
|
||||
N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" id="node2" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src ... dest (10)" labeltooltip="src ... dest (10)" style="dotted" minlen=2]
|
||||
}
|
4
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose4.dot
generated
vendored
4
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose4.dot
generated
vendored
@ -1,4 +0,0 @@
|
||||
digraph "testtitle" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
|
||||
}
|
11
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose5.dot
generated
vendored
11
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose5.dot
generated
vendored
@ -1,11 +0,0 @@
|
||||
digraph "testtitle" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" tooltip="testtitle"] }
|
||||
N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N1_0 [label = "tag1" id="N1_0" fontsize=8 shape=box3d tooltip="10"]
|
||||
N1 -> N1_0 [label=" 10" weight=100 tooltip="10" labeltooltip="10"]
|
||||
NN1_0_0 [label = "tag2" id="NN1_0_0" fontsize=8 shape=box3d tooltip="20"]
|
||||
N1_0 -> NN1_0_0 [label=" 20" weight=100 tooltip="20" labeltooltip="20"]
|
||||
N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" id="node2" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src -> dest (10)" labeltooltip="src -> dest (10)" minlen=2]
|
||||
}
|
7
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose6.dot
generated
vendored
7
src/cmd/vendor/github.com/google/pprof/internal/graph/testdata/compose6.dot
generated
vendored
@ -1,7 +0,0 @@
|
||||
digraph "testtitle" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "label1" [shape=box fontsize=16 label="label1\llabel2\l" URL="http://example.com" target="_blank" tooltip="testtitle"] }
|
||||
N1 [label="src\n10 (10.00%)\nof 25 (25.00%)" id="node1" fontsize=22 shape=box tooltip="src (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N2 [label="dest\n15 (15.00%)\nof 25 (25.00%)" id="node2" fontsize=24 shape=box tooltip="dest (25)" color="#b23c00" fillcolor="#edddd5"]
|
||||
N1 -> N2 [label=" 10" weight=11 color="#b28559" tooltip="src -> dest (10)" labeltooltip="src -> dest (10)"]
|
||||
}
|
47
src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement_test.go
generated
vendored
47
src/cmd/vendor/github.com/google/pprof/internal/measurement/measurement_test.go
generated
vendored
@ -1,47 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package measurement
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestScale(t *testing.T) {
|
||||
for _, tc := range []struct {
|
||||
value int64
|
||||
fromUnit, toUnit string
|
||||
wantValue float64
|
||||
wantUnit string
|
||||
}{
|
||||
{1, "s", "ms", 1000, "ms"},
|
||||
{1, "kb", "b", 1024, "B"},
|
||||
{1, "kbyte", "b", 1024, "B"},
|
||||
{1, "kilobyte", "b", 1024, "B"},
|
||||
{1, "mb", "kb", 1024, "kB"},
|
||||
{1, "gb", "mb", 1024, "MB"},
|
||||
{1024, "gb", "tb", 1, "TB"},
|
||||
{1024, "tb", "pb", 1, "PB"},
|
||||
{2048, "mb", "auto", 2, "GB"},
|
||||
{3.1536e7, "s", "auto", 1, "yrs"},
|
||||
{-1, "s", "ms", -1000, "ms"},
|
||||
{1, "foo", "count", 1, ""},
|
||||
{1, "foo", "bar", 1, "bar"},
|
||||
} {
|
||||
if gotValue, gotUnit := Scale(tc.value, tc.fromUnit, tc.toUnit); gotValue != tc.wantValue || gotUnit != tc.wantUnit {
|
||||
t.Errorf("Scale(%d, %q, %q) = (%f, %q), want (%f, %q)",
|
||||
tc.value, tc.fromUnit, tc.toUnit, gotValue, gotUnit, tc.wantValue, tc.wantUnit)
|
||||
}
|
||||
}
|
||||
}
|
140
src/cmd/vendor/github.com/google/pprof/internal/proftest/proftest.go
generated
vendored
140
src/cmd/vendor/github.com/google/pprof/internal/proftest/proftest.go
generated
vendored
@ -1,140 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package proftest provides some utility routines to test other
|
||||
// packages related to profiles.
|
||||
package proftest
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
"regexp"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Diff compares two byte arrays using the diff tool to highlight the
|
||||
// differences. It is meant for testing purposes to display the
|
||||
// differences between expected and actual output.
|
||||
func Diff(b1, b2 []byte) (data []byte, err error) {
|
||||
f1, err := ioutil.TempFile("", "proto_test")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.Remove(f1.Name())
|
||||
defer f1.Close()
|
||||
|
||||
f2, err := ioutil.TempFile("", "proto_test")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer os.Remove(f2.Name())
|
||||
defer f2.Close()
|
||||
|
||||
f1.Write(b1)
|
||||
f2.Write(b2)
|
||||
|
||||
data, err = exec.Command("diff", "-u", f1.Name(), f2.Name()).CombinedOutput()
|
||||
if len(data) > 0 {
|
||||
// diff exits with a non-zero status when the files don't match.
|
||||
// Ignore that failure as long as we get output.
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
data = []byte(fmt.Sprintf("diff failed: %v\nb1: %q\nb2: %q\n", err, b1, b2))
|
||||
err = nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// EncodeJSON encodes a value into a byte array. This is intended for
|
||||
// testing purposes.
|
||||
func EncodeJSON(x interface{}) []byte {
|
||||
data, err := json.MarshalIndent(x, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
data = append(data, '\n')
|
||||
return data
|
||||
}
|
||||
|
||||
// TestUI implements the plugin.UI interface, triggering test failures
|
||||
// if more than Ignore errors not matching AllowRx are printed.
|
||||
// Also tracks the number of times the error matches AllowRx in
|
||||
// NumAllowRxMatches.
|
||||
type TestUI struct {
|
||||
T *testing.T
|
||||
Ignore int
|
||||
AllowRx string
|
||||
NumAllowRxMatches int
|
||||
Input []string
|
||||
index int
|
||||
}
|
||||
|
||||
// ReadLine returns no input, as no input is expected during testing.
|
||||
func (ui *TestUI) ReadLine(_ string) (string, error) {
|
||||
if ui.index >= len(ui.Input) {
|
||||
return "", io.EOF
|
||||
}
|
||||
input := ui.Input[ui.index]
|
||||
ui.index++
|
||||
if input == "**error**" {
|
||||
return "", fmt.Errorf("Error: %s", input)
|
||||
}
|
||||
return input, nil
|
||||
}
|
||||
|
||||
// Print messages are discarded by the test UI.
|
||||
func (ui *TestUI) Print(args ...interface{}) {
|
||||
}
|
||||
|
||||
// PrintErr messages may trigger an error failure. A fixed number of
|
||||
// error messages are permitted when appropriate.
|
||||
func (ui *TestUI) PrintErr(args ...interface{}) {
|
||||
if ui.AllowRx != "" {
|
||||
if matched, err := regexp.MatchString(ui.AllowRx, fmt.Sprint(args...)); matched || err != nil {
|
||||
if err != nil {
|
||||
ui.T.Errorf("failed to match against regex %q: %v", ui.AllowRx, err)
|
||||
}
|
||||
ui.NumAllowRxMatches++
|
||||
return
|
||||
}
|
||||
}
|
||||
if ui.Ignore > 0 {
|
||||
ui.Ignore--
|
||||
return
|
||||
}
|
||||
// Stringify arguments with fmt.Sprint() to match what default UI
|
||||
// implementation does. Without this Error() calls fmt.Sprintln() which
|
||||
// _always_ adds spaces between arguments, unlike fmt.Sprint() which only
|
||||
// adds them between arguments if neither is string.
|
||||
ui.T.Error("unexpected error: " + fmt.Sprint(args...))
|
||||
}
|
||||
|
||||
// IsTerminal indicates if the UI is an interactive terminal.
|
||||
func (ui *TestUI) IsTerminal() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// WantBrowser indicates whether a browser should be opened with the -http option.
|
||||
func (ui *TestUI) WantBrowser() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// SetAutoComplete is not supported by the test UI.
|
||||
func (ui *TestUI) SetAutoComplete(_ func(string) string) {
|
||||
}
|
414
src/cmd/vendor/github.com/google/pprof/internal/report/report_test.go
generated
vendored
414
src/cmd/vendor/github.com/google/pprof/internal/report/report_test.go
generated
vendored
@ -1,414 +0,0 @@
|
||||
// Copyright 2014 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package report
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"testing"
|
||||
|
||||
"github.com/google/pprof/internal/binutils"
|
||||
"github.com/google/pprof/internal/graph"
|
||||
"github.com/google/pprof/internal/proftest"
|
||||
"github.com/google/pprof/profile"
|
||||
)
|
||||
|
||||
type testcase struct {
|
||||
rpt *Report
|
||||
want string
|
||||
}
|
||||
|
||||
func TestSource(t *testing.T) {
|
||||
const path = "testdata/"
|
||||
|
||||
sampleValue1 := func(v []int64) int64 {
|
||||
return v[1]
|
||||
}
|
||||
|
||||
for _, tc := range []testcase{
|
||||
{
|
||||
rpt: New(
|
||||
testProfile.Copy(),
|
||||
&Options{
|
||||
OutputFormat: List,
|
||||
Symbol: regexp.MustCompile(`.`),
|
||||
TrimPath: "/some/path",
|
||||
|
||||
SampleValue: sampleValue1,
|
||||
SampleUnit: testProfile.SampleType[1].Unit,
|
||||
},
|
||||
),
|
||||
want: path + "source.rpt",
|
||||
},
|
||||
{
|
||||
rpt: New(
|
||||
testProfile.Copy(),
|
||||
&Options{
|
||||
OutputFormat: Dot,
|
||||
CallTree: true,
|
||||
Symbol: regexp.MustCompile(`.`),
|
||||
TrimPath: "/some/path",
|
||||
|
||||
SampleValue: sampleValue1,
|
||||
SampleUnit: testProfile.SampleType[1].Unit,
|
||||
},
|
||||
),
|
||||
want: path + "source.dot",
|
||||
},
|
||||
} {
|
||||
var b bytes.Buffer
|
||||
if err := Generate(&b, tc.rpt, &binutils.Binutils{}); err != nil {
|
||||
t.Fatalf("%s: %v", tc.want, err)
|
||||
}
|
||||
|
||||
gold, err := ioutil.ReadFile(tc.want)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", tc.want, err)
|
||||
}
|
||||
if runtime.GOOS == "windows" {
|
||||
gold = bytes.Replace(gold, []byte("testdata/"), []byte("testdata\\"), -1)
|
||||
}
|
||||
if string(b.String()) != string(gold) {
|
||||
d, err := proftest.Diff(gold, b.Bytes())
|
||||
if err != nil {
|
||||
t.Fatalf("%s: %v", "source", err)
|
||||
}
|
||||
t.Error("source" + "\n" + string(d) + "\n" + "gold:\n" + tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testM = []*profile.Mapping{
|
||||
{
|
||||
ID: 1,
|
||||
HasFunctions: true,
|
||||
HasFilenames: true,
|
||||
HasLineNumbers: true,
|
||||
HasInlineFrames: true,
|
||||
},
|
||||
}
|
||||
|
||||
var testF = []*profile.Function{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "main",
|
||||
Filename: "testdata/source1",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "foo",
|
||||
Filename: "testdata/source1",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "bar",
|
||||
Filename: "testdata/source1",
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Name: "tee",
|
||||
Filename: "/some/path/testdata/source2",
|
||||
},
|
||||
}
|
||||
|
||||
var testL = []*profile.Location{
|
||||
{
|
||||
ID: 1,
|
||||
Mapping: testM[0],
|
||||
Line: []profile.Line{
|
||||
{
|
||||
Function: testF[0],
|
||||
Line: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Mapping: testM[0],
|
||||
Line: []profile.Line{
|
||||
{
|
||||
Function: testF[1],
|
||||
Line: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Mapping: testM[0],
|
||||
Line: []profile.Line{
|
||||
{
|
||||
Function: testF[2],
|
||||
Line: 10,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Mapping: testM[0],
|
||||
Line: []profile.Line{
|
||||
{
|
||||
Function: testF[3],
|
||||
Line: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
ID: 5,
|
||||
Mapping: testM[0],
|
||||
Line: []profile.Line{
|
||||
{
|
||||
Function: testF[3],
|
||||
Line: 8,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var testProfile = &profile.Profile{
|
||||
PeriodType: &profile.ValueType{Type: "cpu", Unit: "millisecond"},
|
||||
Period: 10,
|
||||
DurationNanos: 10e9,
|
||||
SampleType: []*profile.ValueType{
|
||||
{Type: "samples", Unit: "count"},
|
||||
{Type: "cpu", Unit: "cycles"},
|
||||
},
|
||||
Sample: []*profile.Sample{
|
||||
{
|
||||
Location: []*profile.Location{testL[0]},
|
||||
Value: []int64{1, 1},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[2], testL[1], testL[0]},
|
||||
Value: []int64{1, 10},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[4], testL[2], testL[0]},
|
||||
Value: []int64{1, 100},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[3], testL[0]},
|
||||
Value: []int64{1, 1000},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[4], testL[3], testL[0]},
|
||||
Value: []int64{1, 10000},
|
||||
},
|
||||
},
|
||||
Location: testL,
|
||||
Function: testF,
|
||||
Mapping: testM,
|
||||
}
|
||||
|
||||
func TestDisambiguation(t *testing.T) {
|
||||
parent1 := &graph.Node{Info: graph.NodeInfo{Name: "parent1"}}
|
||||
parent2 := &graph.Node{Info: graph.NodeInfo{Name: "parent2"}}
|
||||
child1 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent1}
|
||||
child2 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent2}
|
||||
child3 := &graph.Node{Info: graph.NodeInfo{Name: "child"}, Function: parent1}
|
||||
sibling := &graph.Node{Info: graph.NodeInfo{Name: "sibling"}, Function: parent1}
|
||||
|
||||
n := []*graph.Node{parent1, parent2, child1, child2, child3, sibling}
|
||||
|
||||
wanted := map[*graph.Node]string{
|
||||
parent1: "parent1",
|
||||
parent2: "parent2",
|
||||
child1: "child [1/2]",
|
||||
child2: "child [2/2]",
|
||||
child3: "child [1/2]",
|
||||
sibling: "sibling",
|
||||
}
|
||||
|
||||
g := &graph.Graph{Nodes: n}
|
||||
|
||||
names := getDisambiguatedNames(g)
|
||||
|
||||
for node, want := range wanted {
|
||||
if got := names[node]; got != want {
|
||||
t.Errorf("name %s, got %s, want %s", node.Info.Name, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestFunctionMap(t *testing.T) {
|
||||
|
||||
fm := make(functionMap)
|
||||
nodes := []graph.NodeInfo{
|
||||
{Name: "fun1"},
|
||||
{Name: "fun2", File: "filename"},
|
||||
{Name: "fun1"},
|
||||
{Name: "fun2", File: "filename2"},
|
||||
}
|
||||
|
||||
want := []struct {
|
||||
wantFunction profile.Function
|
||||
wantAdded bool
|
||||
}{
|
||||
{profile.Function{ID: 1, Name: "fun1"}, true},
|
||||
{profile.Function{ID: 2, Name: "fun2", Filename: "filename"}, true},
|
||||
{profile.Function{ID: 1, Name: "fun1"}, false},
|
||||
{profile.Function{ID: 3, Name: "fun2", Filename: "filename2"}, true},
|
||||
}
|
||||
|
||||
for i, tc := range nodes {
|
||||
gotFunc, gotAdded := fm.findOrAdd(tc)
|
||||
if got, want := gotFunc, want[i].wantFunction; *got != want {
|
||||
t.Errorf("%d: got %v, want %v", i, got, want)
|
||||
}
|
||||
if got, want := gotAdded, want[i].wantAdded; got != want {
|
||||
t.Errorf("%d: got %v, want %v", i, got, want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestLegendActiveFilters(t *testing.T) {
|
||||
activeFilterInput := []string{
|
||||
"focus=123|456|789|101112|131415|161718|192021|222324|252627|282930|313233|343536|363738|acbdefghijklmnop",
|
||||
"show=short filter",
|
||||
}
|
||||
expectedLegendActiveFilter := []string{
|
||||
"Active filters:",
|
||||
" focus=123|456|789|101112|131415|161718|192021|222324|252627|282930|313233|343536…",
|
||||
" show=short filter",
|
||||
}
|
||||
legendActiveFilter := legendActiveFilters(activeFilterInput)
|
||||
if len(legendActiveFilter) != len(expectedLegendActiveFilter) {
|
||||
t.Errorf("wanted length %v got length %v", len(expectedLegendActiveFilter), len(legendActiveFilter))
|
||||
}
|
||||
for i := range legendActiveFilter {
|
||||
if legendActiveFilter[i] != expectedLegendActiveFilter[i] {
|
||||
t.Errorf("%d: want \"%v\", got \"%v\"", i, expectedLegendActiveFilter[i], legendActiveFilter[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestComputeTotal(t *testing.T) {
|
||||
p1 := testProfile.Copy()
|
||||
p1.Sample = []*profile.Sample{
|
||||
{
|
||||
Location: []*profile.Location{testL[0]},
|
||||
Value: []int64{1, 1},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[2], testL[1], testL[0]},
|
||||
Value: []int64{1, 10},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[4], testL[2], testL[0]},
|
||||
Value: []int64{1, 100},
|
||||
},
|
||||
}
|
||||
|
||||
p2 := testProfile.Copy()
|
||||
p2.Sample = []*profile.Sample{
|
||||
{
|
||||
Location: []*profile.Location{testL[0]},
|
||||
Value: []int64{1, 1},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[2], testL[1], testL[0]},
|
||||
Value: []int64{1, -10},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[4], testL[2], testL[0]},
|
||||
Value: []int64{1, 100},
|
||||
},
|
||||
}
|
||||
|
||||
p3 := testProfile.Copy()
|
||||
p3.Sample = []*profile.Sample{
|
||||
{
|
||||
Location: []*profile.Location{testL[0]},
|
||||
Value: []int64{10000, 1},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[2], testL[1], testL[0]},
|
||||
Value: []int64{-10, 3},
|
||||
Label: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[2], testL[1], testL[0]},
|
||||
Value: []int64{1000, -10},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[2], testL[1], testL[0]},
|
||||
Value: []int64{-9000, 3},
|
||||
Label: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[2], testL[1], testL[0]},
|
||||
Value: []int64{-1, 3},
|
||||
Label: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[4], testL[2], testL[0]},
|
||||
Value: []int64{100, 100},
|
||||
},
|
||||
{
|
||||
Location: []*profile.Location{testL[2], testL[1], testL[0]},
|
||||
Value: []int64{100, 3},
|
||||
Label: map[string][]string{"pprof::base": {"true"}},
|
||||
},
|
||||
}
|
||||
|
||||
testcases := []struct {
|
||||
desc string
|
||||
prof *profile.Profile
|
||||
value, meanDiv func(v []int64) int64
|
||||
wantTotal int64
|
||||
}{
|
||||
{
|
||||
desc: "no diff base, all positive values, index 1",
|
||||
prof: p1,
|
||||
value: func(v []int64) int64 {
|
||||
return v[0]
|
||||
},
|
||||
wantTotal: 3,
|
||||
},
|
||||
{
|
||||
desc: "no diff base, all positive values, index 2",
|
||||
prof: p1,
|
||||
value: func(v []int64) int64 {
|
||||
return v[1]
|
||||
},
|
||||
wantTotal: 111,
|
||||
},
|
||||
{
|
||||
desc: "no diff base, some negative values",
|
||||
prof: p2,
|
||||
value: func(v []int64) int64 {
|
||||
return v[1]
|
||||
},
|
||||
wantTotal: 111,
|
||||
},
|
||||
{
|
||||
desc: "diff base, some negative values",
|
||||
prof: p3,
|
||||
value: func(v []int64) int64 {
|
||||
return v[0]
|
||||
},
|
||||
wantTotal: 9111,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
if gotTotal := computeTotal(tc.prof, tc.value, tc.meanDiv); gotTotal != tc.wantTotal {
|
||||
t.Errorf("got total %d, want %v", gotTotal, tc.wantTotal)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
185
src/cmd/vendor/github.com/google/pprof/internal/report/source_test.go
generated
vendored
185
src/cmd/vendor/github.com/google/pprof/internal/report/source_test.go
generated
vendored
@ -1,185 +0,0 @@
|
||||
package report
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/pprof/internal/binutils"
|
||||
"github.com/google/pprof/profile"
|
||||
)
|
||||
|
||||
func TestWebList(t *testing.T) {
|
||||
if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
|
||||
t.Skip("weblist only tested on x86-64 linux")
|
||||
}
|
||||
|
||||
cpu := readProfile(filepath.Join("testdata", "sample.cpu"), t)
|
||||
rpt := New(cpu, &Options{
|
||||
OutputFormat: WebList,
|
||||
Symbol: regexp.MustCompile("busyLoop"),
|
||||
SampleValue: func(v []int64) int64 { return v[1] },
|
||||
SampleUnit: cpu.SampleType[1].Unit,
|
||||
})
|
||||
var buf bytes.Buffer
|
||||
if err := Generate(&buf, rpt, &binutils.Binutils{}); err != nil {
|
||||
t.Fatalf("could not generate weblist: %v", err)
|
||||
}
|
||||
output := buf.String()
|
||||
|
||||
for _, expect := range []string{"func busyLoop", "callq", "math.Abs"} {
|
||||
if !strings.Contains(output, expect) {
|
||||
t.Errorf("weblist output does not contain '%s':\n%s", expect, output)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestOpenSourceFile(t *testing.T) {
|
||||
tempdir, err := ioutil.TempDir("", "")
|
||||
if err != nil {
|
||||
t.Fatalf("failed to create temp dir: %v", err)
|
||||
}
|
||||
const lsep = string(filepath.ListSeparator)
|
||||
for _, tc := range []struct {
|
||||
desc string
|
||||
searchPath string
|
||||
trimPath string
|
||||
fs []string
|
||||
path string
|
||||
wantPath string // If empty, error is wanted.
|
||||
}{
|
||||
{
|
||||
desc: "exact absolute path is found",
|
||||
fs: []string{"foo/bar.cc"},
|
||||
path: "$dir/foo/bar.cc",
|
||||
wantPath: "$dir/foo/bar.cc",
|
||||
},
|
||||
{
|
||||
desc: "exact relative path is found",
|
||||
searchPath: "$dir",
|
||||
fs: []string{"foo/bar.cc"},
|
||||
path: "foo/bar.cc",
|
||||
wantPath: "$dir/foo/bar.cc",
|
||||
},
|
||||
{
|
||||
desc: "multiple search path",
|
||||
searchPath: "some/path" + lsep + "$dir",
|
||||
fs: []string{"foo/bar.cc"},
|
||||
path: "foo/bar.cc",
|
||||
wantPath: "$dir/foo/bar.cc",
|
||||
},
|
||||
{
|
||||
desc: "relative path is found in parent dir",
|
||||
searchPath: "$dir/foo/bar",
|
||||
fs: []string{"bar.cc", "foo/bar/baz.cc"},
|
||||
path: "bar.cc",
|
||||
wantPath: "$dir/bar.cc",
|
||||
},
|
||||
{
|
||||
desc: "trims configured prefix",
|
||||
searchPath: "$dir",
|
||||
trimPath: "some-path" + lsep + "/some/remote/path",
|
||||
fs: []string{"my-project/foo/bar.cc"},
|
||||
path: "/some/remote/path/my-project/foo/bar.cc",
|
||||
wantPath: "$dir/my-project/foo/bar.cc",
|
||||
},
|
||||
{
|
||||
desc: "trims heuristically",
|
||||
searchPath: "$dir/my-project",
|
||||
fs: []string{"my-project/foo/bar.cc"},
|
||||
path: "/some/remote/path/my-project/foo/bar.cc",
|
||||
wantPath: "$dir/my-project/foo/bar.cc",
|
||||
},
|
||||
{
|
||||
desc: "error when not found",
|
||||
path: "foo.cc",
|
||||
},
|
||||
} {
|
||||
t.Run(tc.desc, func(t *testing.T) {
|
||||
defer func() {
|
||||
if err := os.RemoveAll(tempdir); err != nil {
|
||||
t.Fatalf("failed to remove dir %q: %v", tempdir, err)
|
||||
}
|
||||
}()
|
||||
for _, f := range tc.fs {
|
||||
path := filepath.Join(tempdir, filepath.FromSlash(f))
|
||||
dir := filepath.Dir(path)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
t.Fatalf("failed to create dir %q: %v", dir, err)
|
||||
}
|
||||
if err := ioutil.WriteFile(path, nil, 0644); err != nil {
|
||||
t.Fatalf("failed to create file %q: %v", path, err)
|
||||
}
|
||||
}
|
||||
tc.searchPath = filepath.FromSlash(strings.Replace(tc.searchPath, "$dir", tempdir, -1))
|
||||
tc.path = filepath.FromSlash(strings.Replace(tc.path, "$dir", tempdir, 1))
|
||||
tc.wantPath = filepath.FromSlash(strings.Replace(tc.wantPath, "$dir", tempdir, 1))
|
||||
if file, err := openSourceFile(tc.path, tc.searchPath, tc.trimPath); err != nil && tc.wantPath != "" {
|
||||
t.Errorf("openSourceFile(%q, %q, %q) = err %v, want path %q", tc.path, tc.searchPath, tc.trimPath, err, tc.wantPath)
|
||||
} else if err == nil {
|
||||
defer file.Close()
|
||||
gotPath := file.Name()
|
||||
if tc.wantPath == "" {
|
||||
t.Errorf("openSourceFile(%q, %q, %q) = %q, want error", tc.path, tc.searchPath, tc.trimPath, gotPath)
|
||||
} else if gotPath != tc.wantPath {
|
||||
t.Errorf("openSourceFile(%q, %q, %q) = %q, want path %q", tc.path, tc.searchPath, tc.trimPath, gotPath, tc.wantPath)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndentation(t *testing.T) {
|
||||
for _, c := range []struct {
|
||||
str string
|
||||
wantIndent int
|
||||
}{
|
||||
{"", 0},
|
||||
{"foobar", 0},
|
||||
{" foo", 2},
|
||||
{"\tfoo", 8},
|
||||
{"\t foo", 9},
|
||||
{" \tfoo", 8},
|
||||
{" \tfoo", 8},
|
||||
{" \tfoo", 16},
|
||||
} {
|
||||
if n := indentation(c.str); n != c.wantIndent {
|
||||
t.Errorf("indentation(%v): got %d, want %d", c.str, n, c.wantIndent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func readProfile(fname string, t *testing.T) *profile.Profile {
|
||||
file, err := os.Open(fname)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: could not open profile: %v", fname, err)
|
||||
}
|
||||
defer file.Close()
|
||||
p, err := profile.Parse(file)
|
||||
if err != nil {
|
||||
t.Fatalf("%s: could not parse profile: %v", fname, err)
|
||||
}
|
||||
|
||||
// Fix file names so they do not include absolute path names.
|
||||
fix := func(s string) string {
|
||||
const testdir = "/internal/report/"
|
||||
pos := strings.Index(s, testdir)
|
||||
if pos == -1 {
|
||||
return s
|
||||
}
|
||||
return s[pos+len(testdir):]
|
||||
}
|
||||
for _, m := range p.Mapping {
|
||||
m.File = fix(m.File)
|
||||
}
|
||||
for _, f := range p.Function {
|
||||
f.Filename = fix(f.Filename)
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
10
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/README.md
generated
vendored
10
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/README.md
generated
vendored
@ -1,10 +0,0 @@
|
||||
sample/ contains a sample program that can be profiled.
|
||||
sample.bin is its x86-64 binary.
|
||||
sample.cpu is a profile generated by sample.bin.
|
||||
|
||||
To update the binary and profile:
|
||||
|
||||
```shell
|
||||
go build -o sample.bin ./sample
|
||||
./sample.bin -cpuprofile sample.cpu
|
||||
```
|
BIN
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.bin
generated
vendored
BIN
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.bin
generated
vendored
Binary file not shown.
BIN
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.cpu
generated
vendored
BIN
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample.cpu
generated
vendored
Binary file not shown.
41
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample/sample.go
generated
vendored
41
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/sample/sample.go
generated
vendored
@ -1,41 +0,0 @@
|
||||
// sample program that is used to produce some of the files in
|
||||
// pprof/internal/report/testdata.
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
)
|
||||
|
||||
var cpuProfile = flag.String("cpuprofile", "", "where to write cpu profile")
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
f, err := os.Create(*cpuProfile)
|
||||
if err != nil {
|
||||
log.Fatal("could not create CPU profile: ", err)
|
||||
}
|
||||
if err := pprof.StartCPUProfile(f); err != nil {
|
||||
log.Fatal("could not start CPU profile: ", err)
|
||||
}
|
||||
defer pprof.StopCPUProfile()
|
||||
busyLoop()
|
||||
}
|
||||
|
||||
func busyLoop() {
|
||||
m := make(map[int]int)
|
||||
for i := 0; i < 1000000; i++ {
|
||||
m[i] = i + 10
|
||||
}
|
||||
var sum float64
|
||||
for i := 0; i < 100; i++ {
|
||||
for _, v := range m {
|
||||
sum += math.Abs(float64(v))
|
||||
}
|
||||
}
|
||||
fmt.Println("Sum", sum)
|
||||
}
|
17
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/source.dot
generated
vendored
17
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/source.dot
generated
vendored
@ -1,17 +0,0 @@
|
||||
digraph "unnamed" {
|
||||
node [style=filled fillcolor="#f8f8f8"]
|
||||
subgraph cluster_L { "Duration: 10s, Total samples = 11111 " [shape=box fontsize=16 label="Duration: 10s, Total samples = 11111 \lShowing nodes accounting for 11111, 100% of 11111 total\l"] }
|
||||
N1 [label="tee\nsource2:8\n10000 (90.00%)" id="node1" fontsize=24 shape=box tooltip="tee testdata/source2:8 (10000)" color="#b20500" fillcolor="#edd6d5"]
|
||||
N2 [label="main\nsource1:2\n1 (0.009%)\nof 11111 (100%)" id="node2" fontsize=9 shape=box tooltip="main testdata/source1:2 (11111)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N3 [label="tee\nsource2:2\n1000 (9.00%)\nof 11000 (99.00%)" id="node3" fontsize=14 shape=box tooltip="tee testdata/source2:2 (11000)" color="#b20000" fillcolor="#edd5d5"]
|
||||
N4 [label="tee\nsource2:8\n100 (0.9%)" id="node4" fontsize=10 shape=box tooltip="tee testdata/source2:8 (100)" color="#b2b0aa" fillcolor="#edecec"]
|
||||
N5 [label="bar\nsource1:10\n10 (0.09%)" id="node5" fontsize=9 shape=box tooltip="bar testdata/source1:10 (10)" color="#b2b2b1" fillcolor="#ededed"]
|
||||
N6 [label="bar\nsource1:10\n0 of 100 (0.9%)" id="node6" fontsize=8 shape=box tooltip="bar testdata/source1:10 (100)" color="#b2b0aa" fillcolor="#edecec"]
|
||||
N7 [label="foo\nsource1:4\n0 of 10 (0.09%)" id="node7" fontsize=8 shape=box tooltip="foo testdata/source1:4 (10)" color="#b2b2b1" fillcolor="#ededed"]
|
||||
N2 -> N3 [label=" 11000" weight=100 penwidth=5 color="#b20000" tooltip="main testdata/source1:2 -> tee testdata/source2:2 (11000)" labeltooltip="main testdata/source1:2 -> tee testdata/source2:2 (11000)"]
|
||||
N3 -> N1 [label=" 10000" weight=91 penwidth=5 color="#b20500" tooltip="tee testdata/source2:2 -> tee testdata/source2:8 (10000)" labeltooltip="tee testdata/source2:2 -> tee testdata/source2:8 (10000)"]
|
||||
N6 -> N4 [label=" 100" color="#b2b0aa" tooltip="bar testdata/source1:10 -> tee testdata/source2:8 (100)" labeltooltip="bar testdata/source1:10 -> tee testdata/source2:8 (100)"]
|
||||
N2 -> N6 [label=" 100" color="#b2b0aa" tooltip="main testdata/source1:2 -> bar testdata/source1:10 (100)" labeltooltip="main testdata/source1:2 -> bar testdata/source1:10 (100)"]
|
||||
N7 -> N5 [label=" 10" color="#b2b2b1" tooltip="foo testdata/source1:4 -> bar testdata/source1:10 (10)" labeltooltip="foo testdata/source1:4 -> bar testdata/source1:10 (10)"]
|
||||
N2 -> N7 [label=" 10" color="#b2b2b1" tooltip="main testdata/source1:2 -> foo testdata/source1:4 (10)" labeltooltip="main testdata/source1:2 -> foo testdata/source1:4 (10)"]
|
||||
}
|
49
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/source.rpt
generated
vendored
49
src/cmd/vendor/github.com/google/pprof/internal/report/testdata/source.rpt
generated
vendored
@ -1,49 +0,0 @@
|
||||
Total: 11111
|
||||
ROUTINE ======================== bar in testdata/source1
|
||||
10 110 (flat, cum) 0.99% of Total
|
||||
. . 5:source1 line 5;
|
||||
. . 6:source1 line 6;
|
||||
. . 7:source1 line 7;
|
||||
. . 8:source1 line 8;
|
||||
. . 9:source1 line 9;
|
||||
10 110 10:source1 line 10;
|
||||
. . 11:source1 line 11;
|
||||
. . 12:source1 line 12;
|
||||
. . 13:source1 line 13;
|
||||
. . 14:source1 line 14;
|
||||
. . 15:source1 line 15;
|
||||
ROUTINE ======================== foo in testdata/source1
|
||||
0 10 (flat, cum) 0.09% of Total
|
||||
. . 1:source1 line 1;
|
||||
. . 2:source1 line 2;
|
||||
. . 3:source1 line 3;
|
||||
. 10 4:source1 line 4;
|
||||
. . 5:source1 line 5;
|
||||
. . 6:source1 line 6;
|
||||
. . 7:source1 line 7;
|
||||
. . 8:source1 line 8;
|
||||
. . 9:source1 line 9;
|
||||
ROUTINE ======================== main in testdata/source1
|
||||
1 11111 (flat, cum) 100% of Total
|
||||
. . 1:source1 line 1;
|
||||
1 11111 2:source1 line 2;
|
||||
. . 3:source1 line 3;
|
||||
. . 4:source1 line 4;
|
||||
. . 5:source1 line 5;
|
||||
. . 6:source1 line 6;
|
||||
. . 7:source1 line 7;
|
||||
ROUTINE ======================== tee in testdata/source2
|
||||
11100 21100 (flat, cum) 189.90% of Total
|
||||
. . 1:source2 line 1;
|
||||
1000 11000 2:source2 line 2;
|
||||
. . 3:source2 line 3;
|
||||
. . 4:source2 line 4;
|
||||
. . 5:source2 line 5;
|
||||
. . 6:source2 line 6;
|
||||
. . 7:source2 line 7;
|
||||
10100 10100 8:source2 line 8;
|
||||
. . 9:source2 line 9;
|
||||
. . 10:source2 line 10;
|
||||
. . 11:source2 line 11;
|
||||
. . 12:source2 line 12;
|
||||
. . 13:source2 line 13;
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user