浏览代码

Merge pull request #1 from google/nowrapper

remove binutils wrappers used for testing
Raul Silvera 9 年前
父节点
当前提交
68ca1d3e7a

+ 64
- 46
internal/binutils/addr2liner.go 查看文件

33
 	sentinel = ^uint64(0)
33
 	sentinel = ^uint64(0)
34
 )
34
 )
35
 
35
 
36
-// Addr2Liner is a connection to an addr2line command for obtaining
36
+// addr2Liner is a connection to an addr2line command for obtaining
37
 // address and line number information from a binary.
37
 // address and line number information from a binary.
38
 type addr2Liner struct {
38
 type addr2Liner struct {
39
-	filename string
40
-	cmd      *exec.Cmd
41
-	in       io.WriteCloser
42
-	out      *bufio.Reader
43
-	err      error
44
-
39
+	rw   lineReaderWriter
45
 	base uint64
40
 	base uint64
46
 }
41
 }
47
 
42
 
43
+// lineReaderWriter is an interface to abstract the I/O to an addr2line
44
+// process. It writes a line of input to the job, and reads its output
45
+// one line at a time.
46
+type lineReaderWriter interface {
47
+	write(string) error
48
+	readLine() (string, error)
49
+	close()
50
+}
51
+
52
+type addr2LinerJob struct {
53
+	cmd *exec.Cmd
54
+	in  io.WriteCloser
55
+	out *bufio.Reader
56
+}
57
+
58
+func (a *addr2LinerJob) write(s string) error {
59
+	_, err := fmt.Fprint(a.in, s+"\n")
60
+	return err
61
+}
62
+
63
+func (a *addr2LinerJob) readLine() (string, error) {
64
+	return a.out.ReadString('\n')
65
+}
66
+
67
+// close releases any resources used by the addr2liner object.
68
+func (a *addr2LinerJob) close() {
69
+	a.in.Close()
70
+	a.cmd.Wait()
71
+}
72
+
48
 // newAddr2liner starts the given addr2liner command reporting
73
 // newAddr2liner starts the given addr2liner command reporting
49
 // information about the given executable file. If file is a shared
74
 // information about the given executable file. If file is a shared
50
 // library, base should be the address at which is was mapped in the
75
 // library, base should be the address at which is was mapped in the
54
 		cmd = defaultAddr2line
79
 		cmd = defaultAddr2line
55
 	}
80
 	}
56
 
81
 
57
-	a := &addr2Liner{
58
-		filename: file,
59
-		base:     base,
60
-		cmd:      exec.Command(cmd, "-aif", "-e", file),
82
+	j := &addr2LinerJob{
83
+		cmd: exec.Command(cmd, "-aif", "-e", file),
61
 	}
84
 	}
62
 
85
 
63
 	var err error
86
 	var err error
64
-	if a.in, err = a.cmd.StdinPipe(); err != nil {
87
+	if j.in, err = j.cmd.StdinPipe(); err != nil {
65
 		return nil, err
88
 		return nil, err
66
 	}
89
 	}
67
 
90
 
68
-	outPipe, err := a.cmd.StdoutPipe()
91
+	outPipe, err := j.cmd.StdoutPipe()
69
 	if err != nil {
92
 	if err != nil {
70
 		return nil, err
93
 		return nil, err
71
 	}
94
 	}
72
 
95
 
73
-	a.out = bufio.NewReader(outPipe)
74
-	if err := a.cmd.Start(); err != nil {
96
+	j.out = bufio.NewReader(outPipe)
97
+	if err := j.cmd.Start(); err != nil {
75
 		return nil, err
98
 		return nil, err
76
 	}
99
 	}
77
-	return a, nil
78
-}
79
 
100
 
80
-// close releases any resources used by the addr2liner object.
81
-func (d *addr2Liner) close() {
82
-	d.in.Close()
83
-	d.cmd.Wait()
101
+	a := &addr2Liner{
102
+		rw:   j,
103
+		base: base,
104
+	}
105
+
106
+	return a, nil
84
 }
107
 }
85
 
108
 
86
-func (d *addr2Liner) readString() (s string) {
87
-	if d.err != nil {
88
-		return ""
89
-	}
90
-	if s, d.err = d.out.ReadString('\n'); d.err != nil {
91
-		return ""
109
+func (d *addr2Liner) readString() (string, error) {
110
+	s, err := d.rw.readLine()
111
+	if err != nil {
112
+		return "", err
92
 	}
113
 	}
93
-	return strings.TrimSpace(s)
114
+	return strings.TrimSpace(s), nil
94
 }
115
 }
95
 
116
 
96
 // readFrame parses the addr2line output for a single address. It
117
 // readFrame parses the addr2line output for a single address. It
97
 // returns a populated plugin.Frame and whether it has reached the end of the
118
 // returns a populated plugin.Frame and whether it has reached the end of the
98
 // data.
119
 // data.
99
 func (d *addr2Liner) readFrame() (plugin.Frame, bool) {
120
 func (d *addr2Liner) readFrame() (plugin.Frame, bool) {
100
-	funcname := d.readString()
101
-
121
+	funcname, err := d.readString()
122
+	if err != nil {
123
+		return plugin.Frame{}, true
124
+	}
102
 	if strings.HasPrefix(funcname, "0x") {
125
 	if strings.HasPrefix(funcname, "0x") {
103
 		// If addr2line returns a hex address we can assume it is the
126
 		// If addr2line returns a hex address we can assume it is the
104
 		// sentinel.  Read and ignore next two lines of output from
127
 		// sentinel.  Read and ignore next two lines of output from
108
 		return plugin.Frame{}, true
131
 		return plugin.Frame{}, true
109
 	}
132
 	}
110
 
133
 
111
-	fileline := d.readString()
112
-	if d.err != nil {
134
+	fileline, err := d.readString()
135
+	if err != nil {
113
 		return plugin.Frame{}, true
136
 		return plugin.Frame{}, true
114
 	}
137
 	}
115
 
138
 
142
 // addrInfo returns the stack frame information for a specific program
165
 // addrInfo returns the stack frame information for a specific program
143
 // address. It returns nil if the address could not be identified.
166
 // address. It returns nil if the address could not be identified.
144
 func (d *addr2Liner) addrInfo(addr uint64) ([]plugin.Frame, error) {
167
 func (d *addr2Liner) addrInfo(addr uint64) ([]plugin.Frame, error) {
145
-	if d.err != nil {
146
-		return nil, d.err
147
-	}
148
-
149
-	if _, d.err = fmt.Fprintf(d.in, "%x\n", addr-d.base); d.err != nil {
150
-		return nil, d.err
168
+	if err := d.rw.write(fmt.Sprintf("%x", addr-d.base)); err != nil {
169
+		return nil, err
151
 	}
170
 	}
152
 
171
 
153
-	if _, d.err = fmt.Fprintf(d.in, "%x\n", sentinel); d.err != nil {
154
-		return nil, d.err
172
+	if err := d.rw.write(fmt.Sprintf("%x", sentinel)); err != nil {
173
+		return nil, err
155
 	}
174
 	}
156
 
175
 
157
-	resp := d.readString()
158
-	if d.err != nil {
159
-		return nil, d.err
176
+	resp, err := d.readString()
177
+	if err != nil {
178
+		return nil, err
160
 	}
179
 	}
161
 
180
 
162
 	if !strings.HasPrefix(resp, "0x") {
181
 	if !strings.HasPrefix(resp, "0x") {
163
-		d.err = fmt.Errorf("unexpected addr2line output: %s", resp)
164
-		return nil, d.err
182
+		return nil, fmt.Errorf("unexpected addr2line output: %s", resp)
165
 	}
183
 	}
166
 
184
 
167
 	var stack []plugin.Frame
185
 	var stack []plugin.Frame
175
 			stack = append(stack, frame)
193
 			stack = append(stack, frame)
176
 		}
194
 		}
177
 	}
195
 	}
178
-	return stack, d.err
196
+	return stack, nil
179
 }
197
 }

+ 19
- 3
internal/binutils/binutils.go 查看文件

89
 		// Update the command invocations if not initialized.
89
 		// Update the command invocations if not initialized.
90
 		b.SetTools("")
90
 		b.SetTools("")
91
 	}
91
 	}
92
-	return disassemble(b.objdump, file, start, end)
92
+	cmd := exec.Command(b.objdump, "-d", "-C", "--no-show-raw-insn", "-l",
93
+		fmt.Sprintf("--start-address=%#x", start),
94
+		fmt.Sprintf("--stop-address=%#x", end),
95
+		file)
96
+	out, err := cmd.Output()
97
+	if err != nil {
98
+		return nil, fmt.Errorf("%v: %v", cmd.Args, err)
99
+	}
100
+
101
+	return disassemble(out)
93
 }
102
 }
94
 
103
 
95
 // Open satisfies the plugin.ObjTool interface.
104
 // Open satisfies the plugin.ObjTool interface.
191
 }
200
 }
192
 
201
 
193
 func (f *file) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) {
202
 func (f *file) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) {
194
-	return findSymbols(f.b.nm, f.name, r, addr)
203
+	// Get from nm a list of symbols sorted by address.
204
+	cmd := exec.Command(f.b.nm, "-n", f.name)
205
+	out, err := cmd.Output()
206
+	if err != nil {
207
+		return nil, fmt.Errorf("%v: %v", cmd.Args, err)
208
+	}
209
+
210
+	return findSymbols(out, f.name, r, addr)
195
 }
211
 }
196
 
212
 
197
 // fileNM implements the binutils.ObjFile interface, using 'nm' to map
213
 // fileNM implements the binutils.ObjFile interface, using 'nm' to map
235
 
251
 
236
 func (f *fileAddr2Line) Close() error {
252
 func (f *fileAddr2Line) Close() error {
237
 	if f.addr2liner != nil {
253
 	if f.addr2liner != nil {
238
-		f.addr2liner.close()
254
+		f.addr2liner.rw.close()
239
 		f.addr2liner = nil
255
 		f.addr2liner = nil
240
 	}
256
 	}
241
 	return nil
257
 	return nil

+ 47
- 6
internal/binutils/binutils_test.go 查看文件

37
 func TestAddr2Liner(t *testing.T) {
37
 func TestAddr2Liner(t *testing.T) {
38
 	const offset = 0x500
38
 	const offset = 0x500
39
 
39
 
40
-	a, err := newAddr2Liner("testdata/wrapper/addr2line", "executable", offset)
41
-	if err != nil {
42
-		t.Fatalf("Addr2Liner Open: %v", err)
43
-	}
44
-
40
+	a := addr2Liner{&mockAddr2liner{}, offset}
45
 	for i := 1; i < 8; i++ {
41
 	for i := 1; i < 8; i++ {
46
 		addr := i*0x1000 + offset
42
 		addr := i*0x1000 + offset
47
 		s, err := a.addrInfo(uint64(addr))
43
 		s, err := a.addrInfo(uint64(addr))
67
 	if len(s) != 0 {
63
 	if len(s) != 0 {
68
 		t.Fatalf("AddrInfo(0xFFFF): got len==%d, want 0", len(s))
64
 		t.Fatalf("AddrInfo(0xFFFF): got len==%d, want 0", len(s))
69
 	}
65
 	}
70
-	a.close()
66
+	a.rw.close()
67
+}
68
+
69
+type mockAddr2liner struct {
70
+	output []string
71
+}
72
+
73
+func (a *mockAddr2liner) write(s string) error {
74
+	var lines []string
75
+	switch s {
76
+	case "1000":
77
+		lines = []string{"_Z3fooid.clone2", "file1000:1000"}
78
+	case "2000":
79
+		lines = []string{"_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
80
+	case "3000":
81
+		lines = []string{"_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
82
+	case "4000":
83
+		lines = []string{"fun4000", "file4000:4000", "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
84
+	case "5000":
85
+		lines = []string{"fun5000", "file5000:5000", "fun4000", "file4000:4000", "_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm", "file3000:3000", "_ZNSaIiEC1Ev.clone18", "file2000:2000", "_Z3fooid.clone2", "file1000:1000"}
86
+	case "6000":
87
+		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"}
88
+	case "7000":
89
+		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"}
90
+	case "8000":
91
+		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"}
92
+	case "9000":
93
+		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"}
94
+	default:
95
+		lines = []string{"??", "??:0"}
96
+	}
97
+	a.output = append(a.output, "0x"+s)
98
+	a.output = append(a.output, lines...)
99
+	return nil
100
+}
101
+
102
+func (a *mockAddr2liner) readLine() (string, error) {
103
+	if len(a.output) == 0 {
104
+		return "", fmt.Errorf("end of file")
105
+	}
106
+	next := a.output[0]
107
+	a.output = a.output[1:]
108
+	return next, nil
109
+}
110
+
111
+func (a *mockAddr2liner) close() {
71
 }
112
 }
72
 
113
 
73
 func TestAddr2LinerLookup(t *testing.T) {
114
 func TestAddr2LinerLookup(t *testing.T) {

+ 6
- 24
internal/binutils/disasm.go 查看文件

16
 
16
 
17
 import (
17
 import (
18
 	"bytes"
18
 	"bytes"
19
-	"fmt"
20
 	"io"
19
 	"io"
21
-	"os/exec"
22
 	"regexp"
20
 	"regexp"
23
 	"strconv"
21
 	"strconv"
24
 
22
 
32
 	objdumpOutputFileLine = regexp.MustCompile(`^(.*):([0-9]+)`)
30
 	objdumpOutputFileLine = regexp.MustCompile(`^(.*):([0-9]+)`)
33
 )
31
 )
34
 
32
 
35
-func findSymbols(nm, file string, r *regexp.Regexp, address uint64) ([]*plugin.Sym, error) {
36
-	// Get from nm a list of symbols sorted by address.
37
-	cmd := exec.Command(nm, "-n", file)
38
-	out, err := cmd.Output()
39
-	if err != nil {
40
-		return nil, fmt.Errorf("%v: %v", cmd.Args, err)
41
-	}
42
-
33
+func findSymbols(syms []byte, file string, r *regexp.Regexp, address uint64) ([]*plugin.Sym, error) {
43
 	// Collect all symbols from the nm output, grouping names mapped to
34
 	// Collect all symbols from the nm output, grouping names mapped to
44
 	// the same address into a single symbol.
35
 	// the same address into a single symbol.
45
 	var symbols []*plugin.Sym
36
 	var symbols []*plugin.Sym
46
 	names, start := []string{}, uint64(0)
37
 	names, start := []string{}, uint64(0)
47
-	buf := bytes.NewBuffer(out)
38
+	buf := bytes.NewBuffer(syms)
48
 	for symAddr, name, err := nextSymbol(buf); err == nil; symAddr, name, err = nextSymbol(buf) {
39
 	for symAddr, name, err := nextSymbol(buf); err == nil; symAddr, name, err = nextSymbol(buf) {
49
 		if err != nil {
40
 		if err != nil {
50
 			return nil, err
41
 			return nil, err
88
 	return nil
79
 	return nil
89
 }
80
 }
90
 
81
 
91
-// disassemble returns the assembly instructions in a function from a
92
-// binary file. It uses objdump to obtain the assembly listing.
93
-func disassemble(objdump string, file string, start, stop uint64) ([]plugin.Inst, error) {
94
-	cmd := exec.Command(objdump, "-d", "-C", "--no-show-raw-insn", "-l",
95
-		fmt.Sprintf("--start-address=%#x", start),
96
-		fmt.Sprintf("--stop-address=%#x", stop),
97
-		file)
98
-	out, err := cmd.Output()
99
-	if err != nil {
100
-		return nil, fmt.Errorf("%v: %v", cmd.Args, err)
101
-	}
102
-
103
-	buf := bytes.NewBuffer(out)
82
+// disassemble parses the output of the objdump command and returns
83
+// the assembly instructions in a slice.
84
+func disassemble(asm []byte) ([]plugin.Inst, error) {
85
+	buf := bytes.NewBuffer(asm)
104
 	file, line := "", 0
86
 	file, line := "", 0
105
 	var assembly []plugin.Inst
87
 	var assembly []plugin.Inst
106
 	for {
88
 	for {

+ 28
- 7
internal/binutils/disasm_test.go 查看文件

22
 	"github.com/google/pprof/internal/plugin"
22
 	"github.com/google/pprof/internal/plugin"
23
 )
23
 )
24
 
24
 
25
-// TestFindSymbols tests the FindSymbols routine by using a fake nm
26
-// script.
25
+// TestFindSymbols tests the FindSymbols routine using a hardcoded nm output.
27
 func TestFindSymbols(t *testing.T) {
26
 func TestFindSymbols(t *testing.T) {
28
 	type testcase struct {
27
 	type testcase struct {
29
-		query string
30
-		want  []plugin.Sym
28
+		query, syms string
29
+		want        []plugin.Sym
31
 	}
30
 	}
32
 
31
 
32
+	testsyms := `0000000000001000 t lineA001
33
+0000000000001000 t lineA002
34
+0000000000001000 t line1000
35
+0000000000002000 t line200A
36
+0000000000002000 t line2000
37
+0000000000002000 t line200B
38
+0000000000003000 t line3000
39
+0000000000003000 t _ZNK4DumbclEPKc
40
+0000000000003000 t lineB00C
41
+0000000000003000 t line300D
42
+0000000000004000 t _the_end
43
+	`
33
 	testcases := []testcase{
44
 	testcases := []testcase{
34
 		{
45
 		{
35
 			"line.*[AC]",
46
 			"line.*[AC]",
47
+			testsyms,
36
 			[]plugin.Sym{
48
 			[]plugin.Sym{
37
 				{[]string{"lineA001"}, "object.o", 0x1000, 0x1FFF},
49
 				{[]string{"lineA001"}, "object.o", 0x1000, 0x1FFF},
38
 				{[]string{"line200A"}, "object.o", 0x2000, 0x2FFF},
50
 				{[]string{"line200A"}, "object.o", 0x2000, 0x2FFF},
41
 		},
53
 		},
42
 		{
54
 		{
43
 			"Dumb::operator",
55
 			"Dumb::operator",
56
+			testsyms,
44
 			[]plugin.Sym{
57
 			[]plugin.Sym{
45
 				{[]string{"Dumb::operator()(char const*) const"}, "object.o", 0x3000, 0x3FFF},
58
 				{[]string{"Dumb::operator()(char const*) const"}, "object.o", 0x3000, 0x3FFF},
46
 			},
59
 			},
47
 		},
60
 		},
48
 	}
61
 	}
49
 
62
 
50
-	const nm = "testdata/wrapper/nm"
51
 	for _, tc := range testcases {
63
 	for _, tc := range testcases {
52
-		syms, err := findSymbols(nm, "object.o", regexp.MustCompile(tc.query), 0)
64
+		syms, err := findSymbols([]byte(tc.syms), "object.o", regexp.MustCompile(tc.query), 0)
53
 		if err != nil {
65
 		if err != nil {
54
 			t.Fatalf("%q: findSymbols: %v", tc.query, err)
66
 			t.Fatalf("%q: findSymbols: %v", tc.query, err)
55
 		}
67
 		}
92
 func TestFunctionAssembly(t *testing.T) {
104
 func TestFunctionAssembly(t *testing.T) {
93
 	type testcase struct {
105
 	type testcase struct {
94
 		s    plugin.Sym
106
 		s    plugin.Sym
107
+		asm  string
95
 		want []plugin.Inst
108
 		want []plugin.Inst
96
 	}
109
 	}
97
 	testcases := []testcase{
110
 	testcases := []testcase{
98
 		{
111
 		{
99
 			plugin.Sym{[]string{"symbol1"}, "", 0x1000, 0x1FFF},
112
 			plugin.Sym{[]string{"symbol1"}, "", 0x1000, 0x1FFF},
113
+			`  1000: instruction one
114
+  1001: instruction two
115
+  1002: instruction three
116
+  1003: instruction four
117
+`,
100
 			[]plugin.Inst{
118
 			[]plugin.Inst{
101
 				{0x1000, "instruction one", "", 0},
119
 				{0x1000, "instruction one", "", 0},
102
 				{0x1001, "instruction two", "", 0},
120
 				{0x1001, "instruction two", "", 0},
106
 		},
124
 		},
107
 		{
125
 		{
108
 			plugin.Sym{[]string{"symbol2"}, "", 0x2000, 0x2FFF},
126
 			plugin.Sym{[]string{"symbol2"}, "", 0x2000, 0x2FFF},
127
+			`  2000: instruction one
128
+  2001: instruction two
129
+`,
109
 			[]plugin.Inst{
130
 			[]plugin.Inst{
110
 				{0x2000, "instruction one", "", 0},
131
 				{0x2000, "instruction one", "", 0},
111
 				{0x2001, "instruction two", "", 0},
132
 				{0x2001, "instruction two", "", 0},
116
 	const objdump = "testdata/wrapper/objdump"
137
 	const objdump = "testdata/wrapper/objdump"
117
 
138
 
118
 	for _, tc := range testcases {
139
 	for _, tc := range testcases {
119
-		insns, err := disassemble(objdump, "object.o", tc.s.Start, tc.s.End)
140
+		insns, err := disassemble([]byte(tc.asm))
120
 		if err != nil {
141
 		if err != nil {
121
 			t.Fatalf("FunctionAssembly: %v", err)
142
 			t.Fatalf("FunctionAssembly: %v", err)
122
 		}
143
 		}

+ 0
- 85
internal/binutils/testdata/wrapper/addr2line 查看文件

1
-#!/bin/bash
2
-# Copyright 2014 Google Inc. All Rights Reserved.
3
-#
4
-# Licensed under the Apache License, Version 2.0 (the "License");
5
-# you may not use this file except in compliance with the License.
6
-# You may obtain a copy of the License at
7
-#
8
-#     http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-# Unless required by applicable law or agreed to in writing, software
11
-# distributed under the License is distributed on an "AS IS" BASIS,
12
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-# See the License for the specific language governing permissions and
14
-# limitations under the License.
15
-#
16
-# addr2line stub for testing of addr2liner.
17
-# Will recognize (and ignore) the -aiCfej options.
18
-#
19
-# Accepts addresses 1000 to 9000 and output multiple frames of the form:
20
-#   0x9000/fun9000/file9000:9000
21
-#   0x8000/fun8000/file8000:8000
22
-#   0x7000/fun7000/file7000:7000
23
-#   ...
24
-#   0x1000/fun1000/file1000:1000
25
-#
26
-# Returns ??/??/??:0 for all other inputs.
27
-
28
-while getopts aiCfe:j: opt; do
29
-  case "$opt" in
30
-    a|i|C|f|e|j) ;;
31
-    *)
32
-      echo "unrecognized option: $1" >&2
33
-      exit 1
34
-  esac
35
-done
36
-
37
-while read input
38
-do
39
-  address="$input"
40
-  
41
-  # remove 0x from input.
42
-  case "${address}" in
43
-    0x*)
44
-      address=$(printf '%x' "$address")
45
-      ;;
46
-    *)
47
-      address=$(printf '%x' "0x$address")
48
-  esac
49
-
50
-  printf '0x%x\n' "0x$address"
51
-  loop=1
52
-  while [ $loop -eq 1 ]
53
-  do
54
-    # prepare default output.
55
-    output2="fun${address}"
56
-    output3="file${address}:${address}"
57
-
58
-    # specialize output for selected cases.
59
-	  case "${address}" in
60
-      1000)
61
-        output2="_Z3fooid.clone2"
62
-        loop=0
63
-        ;;
64
-      2000)
65
-        output2="_ZNSaIiEC1Ev.clone18"
66
-        address=1000
67
-        ;;
68
-      3000)
69
-        output2="_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm"
70
-        address=2000
71
-        ;;
72
-      [4-9]000)
73
-        address=$(expr ${address} - 1000)
74
-        ;;
75
-      *)
76
-        output2='??'
77
-        output3='??:0'
78
-        loop=0
79
-    esac
80
-
81
-    echo "$output2"
82
-    echo "$output3"
83
-  done
84
-done
85
-exit 0

+ 0
- 62
internal/binutils/testdata/wrapper/nm 查看文件

1
-#!/bin/bash
2
-# Copyright 2014 Google Inc. All Rights Reserved.
3
-#
4
-# Licensed under the Apache License, Version 2.0 (the "License");
5
-# you may not use this file except in compliance with the License.
6
-# You may obtain a copy of the License at
7
-#
8
-#     http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-# Unless required by applicable law or agreed to in writing, software
11
-# distributed under the License is distributed on an "AS IS" BASIS,
12
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-# See the License for the specific language governing permissions and
14
-# limitations under the License.
15
-#
16
-# nm stub for testing of listing.
17
-# Will recognize (and ignore) the -nC options.
18
-#
19
-# Outputs fixed nm output.
20
-
21
-while getopts nC opt; do
22
-  case "$opt" in
23
-    n) ;;
24
-    C) demangle=1;;
25
-    *)
26
-      echo "unrecognized option: $1" >&2
27
-      exit 1
28
-  esac
29
-done
30
-
31
-if [ $demangle ] 
32
-then
33
-  cat <<EOF
34
-0000000000001000 t lineA001
35
-0000000000001000 t lineA002
36
-0000000000001000 t line1000
37
-0000000000002000 t line200A
38
-0000000000002000 t line2000
39
-0000000000002000 t line200B
40
-0000000000003000 t line3000
41
-0000000000003000 t Dumb::operator()(char const*) const
42
-0000000000003000 t lineB00C
43
-0000000000003000 t line300D
44
-0000000000004000 t _the_end
45
-EOF
46
-  exit 0
47
-fi
48
-
49
-cat <<EOF
50
-0000000000001000 t lineA001
51
-0000000000001000 t lineA002
52
-0000000000001000 t line1000
53
-0000000000002000 t line200A
54
-0000000000002000 t line2000
55
-0000000000002000 t line200B
56
-0000000000003000 t line3000
57
-0000000000003000 t _ZNK4DumbclEPKc
58
-0000000000003000 t lineB00C
59
-0000000000003000 t line300D
60
-0000000000004000 t _the_end
61
-EOF
62
-exit 0

+ 0
- 59
internal/binutils/testdata/wrapper/objdump 查看文件

1
-#!/bin/bash
2
-# Copyright 2014 Google Inc. All Rights Reserved.
3
-#
4
-# Licensed under the Apache License, Version 2.0 (the "License");
5
-# you may not use this file except in compliance with the License.
6
-# You may obtain a copy of the License at
7
-#
8
-#     http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-# Unless required by applicable law or agreed to in writing, software
11
-# distributed under the License is distributed on an "AS IS" BASIS,
12
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-# See the License for the specific language governing permissions and
14
-# limitations under the License.
15
-#
16
-# objdump stub for testing of listing.
17
-# Will recognize (and ignore) the -nC options.
18
-#
19
-# Outputs fixed nm output.
20
-
21
-START=0
22
-STOP=0
23
-while [ $# -gt 1 ] ; do 
24
- case "$1" in 
25
-   --start-address=*) START=$(echo $1 | sed 's/.*=//') ;;
26
-   --stop-address=*) STOP=$(echo $1 | sed 's/.*=//') ;; 
27
-   --no-show-raw-insn|-d|-C|-n|-l) ;;
28
-   *) echo "Unrecognized option $1"
29
-     exit 1
30
- esac
31
- shift
32
-done
33
-
34
-case "$START$STOP" in 
35
-  "0x10000x1fff")
36
-  cat <<EOF
37
-  1000: instruction one
38
-  1001: instruction two
39
-  1002: instruction three
40
-  1003: instruction four
41
-EOF
42
-  ;;
43
-  "0x20000x2fff")
44
-  cat <<EOF
45
-  2000: instruction one
46
-  2001: instruction two
47
-EOF
48
-  ;;
49
-  "0x30000x3fff")
50
-  cat <<EOF
51
-  3000: instruction one
52
-  3001: instruction two
53
-  3002: instruction three
54
-  3003: instruction four
55
-  3004: instruction five
56
-EOF
57
-  ;;
58
-esac
59
-exit 0

+ 80
- 10
internal/driver/driver_test.go 查看文件

18
 	"bytes"
18
 	"bytes"
19
 	"fmt"
19
 	"fmt"
20
 	"io/ioutil"
20
 	"io/ioutil"
21
-	"os"
21
+	"regexp"
22
 	"strconv"
22
 	"strconv"
23
 	"strings"
23
 	"strings"
24
 	"testing"
24
 	"testing"
25
 	"time"
25
 	"time"
26
 
26
 
27
-	"github.com/google/pprof/internal/binutils"
28
 	"github.com/google/pprof/internal/plugin"
27
 	"github.com/google/pprof/internal/plugin"
29
 	"github.com/google/pprof/internal/proftest"
28
 	"github.com/google/pprof/internal/proftest"
30
 	"github.com/google/pprof/internal/symbolz"
29
 	"github.com/google/pprof/internal/symbolz"
35
 	// Override weblist command to collect output in buffer
34
 	// Override weblist command to collect output in buffer
36
 	pprofCommands["weblist"].postProcess = nil
35
 	pprofCommands["weblist"].postProcess = nil
37
 
36
 
38
-	// Update PATH to use fake dot for svg output
39
-	os.Setenv("PATH", "testdata/wrapper"+":"+os.Getenv("PATH"))
40
-
41
 	testcase := []struct {
37
 	testcase := []struct {
42
 		flags, source string
38
 		flags, source string
43
 	}{
39
 	}{
58
 		{"dot,lines,flat,focus=[12]00", "heap"},
54
 		{"dot,lines,flat,focus=[12]00", "heap"},
59
 		{"dot,addresses,flat,ignore=[X3]002,focus=[X1]000", "contention"},
55
 		{"dot,addresses,flat,ignore=[X3]002,focus=[X1]000", "contention"},
60
 		{"dot,files,cum", "contention"},
56
 		{"dot,files,cum", "contention"},
61
-		{"svg", "cpu"},
62
 		{"tags", "cpu"},
57
 		{"tags", "cpu"},
63
 		{"tags,tagignore=tag[13],tagfocus=key[12]", "cpu"},
58
 		{"tags,tagignore=tag[13],tagfocus=key[12]", "cpu"},
64
 		{"traces", "cpu"},
59
 		{"traces", "cpu"},
137
 		o2 := setDefaults(nil)
132
 		o2 := setDefaults(nil)
138
 		o2.Flagset = f
133
 		o2.Flagset = f
139
 		o2.Sym = testSymbolizeDemangler{}
134
 		o2.Sym = testSymbolizeDemangler{}
140
-		o2.Obj = new(binutils.Binutils)
135
+		o2.Obj = new(mockObjTool)
141
 
136
 
142
 		if err := PProf(o2); err != nil {
137
 		if err := PProf(o2); err != nil {
143
 			t.Errorf("%s: %v", tc.source, err)
138
 			t.Errorf("%s: %v", tc.source, err)
325
 			"divide_by":    1.0,
320
 			"divide_by":    1.0,
326
 		},
321
 		},
327
 		strings: map[string]string{
322
 		strings: map[string]string{
328
-			"tools": "testdata/wrapper",
329
-			"unit":  "minimum",
323
+			"unit": "minimum",
330
 		},
324
 		},
331
 	}
325
 	}
332
 }
326
 }
972
 
966
 
973
 	o := setDefaults(nil)
967
 	o := setDefaults(nil)
974
 	o.Flagset = f
968
 	o.Flagset = f
975
-	o.Obj = new(binutils.Binutils)
969
+	o.Obj = new(mockObjTool)
976
 	src, cmd, err := parseFlags(o)
970
 	src, cmd, err := parseFlags(o)
977
 	if err != nil {
971
 	if err != nil {
978
 		t.Fatalf("parseFlags: %v", err)
972
 		t.Fatalf("parseFlags: %v", err)
1002
 		}
996
 		}
1003
 	}
997
 	}
1004
 }
998
 }
999
+
1000
+type mockObjTool struct{}
1001
+
1002
+func (*mockObjTool) Open(file string, start, limit, offset uint64) (plugin.ObjFile, error) {
1003
+	return &mockFile{file, "abcdef", 0}, nil
1004
+}
1005
+
1006
+func (m *mockObjTool) Disasm(file string, start, end uint64) ([]plugin.Inst, error) {
1007
+	switch start {
1008
+	case 0x1000:
1009
+		return []plugin.Inst{
1010
+			{0x1000, "instruction one", "", 0},
1011
+			{0x1001, "instruction two", "", 0},
1012
+			{0x1002, "instruction three", "", 0},
1013
+			{0x1003, "instruction four", "", 0},
1014
+		}, nil
1015
+	case 0x3000:
1016
+		return []plugin.Inst{
1017
+			{0x3000, "instruction one", "", 0},
1018
+			{0x3001, "instruction two", "", 0},
1019
+			{0x3002, "instruction three", "", 0},
1020
+			{0x3003, "instruction four", "", 0},
1021
+			{0x3004, "instruction five", "", 0},
1022
+		}, nil
1023
+	}
1024
+	return nil, fmt.Errorf("unimplemented")
1025
+}
1026
+
1027
+type mockFile struct {
1028
+	name, buildId string
1029
+	base          uint64
1030
+}
1031
+
1032
+// Name returns the underlyinf file name, if available
1033
+func (m *mockFile) Name() string {
1034
+	return m.name
1035
+}
1036
+
1037
+// Base returns the base address to use when looking up symbols in the file.
1038
+func (m *mockFile) Base() uint64 {
1039
+	return m.base
1040
+}
1041
+
1042
+// BuildID returns the GNU build ID of the file, or an empty string.
1043
+func (m *mockFile) BuildID() string {
1044
+	return m.buildId
1045
+}
1046
+
1047
+// SourceLine reports the source line information for a given
1048
+// address in the file. Due to inlining, the source line information
1049
+// is in general a list of positions representing a call stack,
1050
+// with the leaf function first.
1051
+func (*mockFile) SourceLine(addr uint64) ([]plugin.Frame, error) {
1052
+	return nil, fmt.Errorf("unimplemented")
1053
+}
1054
+
1055
+// Symbols returns a list of symbols in the object file.
1056
+// If r is not nil, Symbols restricts the list to symbols
1057
+// with names matching the regular expression.
1058
+// If addr is not zero, Symbols restricts the list to symbols
1059
+// containing that address.
1060
+func (m *mockFile) Symbols(r *regexp.Regexp, addr uint64) ([]*plugin.Sym, error) {
1061
+	switch r.String() {
1062
+	case "line[13]":
1063
+		return []*plugin.Sym{
1064
+			{[]string{"line1000"}, m.name, 0x1000, 0x1003},
1065
+			{[]string{"line3000"}, m.name, 0x3000, 0x3004},
1066
+		}, nil
1067
+	}
1068
+	return nil, fmt.Errorf("unimplemented")
1069
+}
1070
+
1071
+// Close closes the file, releasing associated resources.
1072
+func (*mockFile) Close() error {
1073
+	return nil
1074
+}

+ 0
- 55
internal/driver/testdata/cppbench.svg 查看文件

1
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
-<!-- Generated by graphviz version 2.36.0 (20140111.2315)
5
- -->
6
-<!-- Title: cppbench_server_main Pages: 1 -->
7
-<svg width="555pt" height="210pt"
8
- viewBox="0.00 0.00 555.00 210.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
9
-<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 206)">
10
-<title>cppbench_server_main</title>
11
-<polygon fill="white" stroke="none" points="-4,4 -4,-206 551,-206 551,4 -4,4"/>
12
-<g id="clust1" class="cluster"><title>cluster_L</title>
13
-<polygon fill="none" stroke="black" points="8,-80 8,-194 402,-194 402,-80 8,-80"/>
14
-</g>
15
-<!-- File: cppbench_server_main -->
16
-<g id="node1" class="node"><title>File: cppbench_server_main</title>
17
-<polygon fill="#f8f8f8" stroke="black" points="394.25,-186 15.75,-186 15.75,-88 394.25,-88 394.25,-186"/>
18
-<text text-anchor="start" x="23.5" y="-169.2" font-family="Times,serif" font-size="16.00">File: cppbench_server_main</text>
19
-<text text-anchor="start" x="23.5" y="-151.2" font-family="Times,serif" font-size="16.00">Type: cpu</text>
20
-<text text-anchor="start" x="23.5" y="-133.2" font-family="Times,serif" font-size="16.00">0 of 7120000000ns total (0%)</text>
21
-<text text-anchor="start" x="23.5" y="-115.2" font-family="Times,serif" font-size="16.00">Dropped 56 nodes (cum &lt;= 35600000ns)</text>
22
-<text text-anchor="start" x="23.5" y="-97.2" font-family="Times,serif" font-size="16.00">Showing top 2 nodes out of 38 (cum &gt;= 7070000000ns)</text>
23
-</g>
24
-<!-- N1 -->
25
-<g id="node2" class="node"><title>N1</title>
26
-<g id="a_node2"><a xlink:title="start_thread (7120000000ns)">
27
-<polygon fill="#f8f8f8" stroke="black" points="513,-155 413,-155 413,-119 513,-119 513,-155"/>
28
-<text text-anchor="middle" x="463" y="-139.6" font-family="Times,serif" font-size="8.00">start_thread</text>
29
-<text text-anchor="middle" x="463" y="-130.6" font-family="Times,serif" font-size="8.00">0 of 7120000000ns(100%)</text>
30
-</a>
31
-</g>
32
-</g>
33
-<!-- N2 -->
34
-<g id="node3" class="node"><title>N2</title>
35
-<g id="a_node3"><a xlink:title="RunWorkerLoop (7070000000ns)">
36
-<polygon fill="#f8f8f8" stroke="black" points="515.5,-36 410.5,-36 410.5,-0 515.5,-0 515.5,-36"/>
37
-<text text-anchor="middle" x="463" y="-20.6" font-family="Times,serif" font-size="8.00">RunWorkerLoop</text>
38
-<text text-anchor="middle" x="463" y="-11.6" font-family="Times,serif" font-size="8.00">0 of 7070000000ns(99.30%)</text>
39
-</a>
40
-</g>
41
-</g>
42
-<!-- N1&#45;&gt;N2 -->
43
-<g id="edge1" class="edge"><title>N1&#45;&gt;N2</title>
44
-<g id="a_edge1"><a xlink:title="start_thread ... RunWorkerLoop (7070000000ns)">
45
-<path fill="none" stroke="black" stroke-width="5" stroke-dasharray="1,5" d="M463,-118.987C463,-99.9242 463,-68.7519 463,-46.2768"/>
46
-<polygon fill="black" stroke="black" stroke-width="5" points="467.375,-46.0333 463,-36.0333 458.625,-46.0334 467.375,-46.0333"/>
47
-</a>
48
-</g>
49
-<g id="a_edge1&#45;label"><a xlink:title="start_thread ... RunWorkerLoop (7070000000ns)">
50
-<text text-anchor="middle" x="505" y="-58.3" font-family="Times,serif" font-size="14.00"> 7070000000ns</text>
51
-</a>
52
-</g>
53
-</g>
54
-</g>
55
-</svg>

+ 0
- 54
internal/driver/testdata/pprof.cpu.svg 查看文件

1
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
3
- "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
4
-<!-- Generated by graphviz version 2.36.0 (20140111.2315)
5
- -->
6
-<!-- Title: cppbench_server_main Pages: 1 -->
7
-<svg width="100%" height="100%" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
8
-<script></script><g id="viewport" transform="scale(0.5,0.5) translate(0,0)"><g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 206)">
9
-<title>cppbench_server_main</title>
10
-<polygon fill="white" stroke="none" points="-4,4 -4,-206 551,-206 551,4 -4,4"/>
11
-<g id="clust1" class="cluster"><title>cluster_L</title>
12
-<polygon fill="none" stroke="black" points="8,-80 8,-194 402,-194 402,-80 8,-80"/>
13
-</g>
14
-<!-- File: cppbench_server_main -->
15
-<g id="node1" class="node"><title>File: cppbench_server_main</title>
16
-<polygon fill="#f8f8f8" stroke="black" points="394.25,-186 15.75,-186 15.75,-88 394.25,-88 394.25,-186"/>
17
-<text text-anchor="start" x="23.5" y="-169.2" font-family="Times,serif" font-size="16.00">File: cppbench_server_main</text>
18
-<text text-anchor="start" x="23.5" y="-151.2" font-family="Times,serif" font-size="16.00">Type: cpu</text>
19
-<text text-anchor="start" x="23.5" y="-133.2" font-family="Times,serif" font-size="16.00">0 of 7120000000ns total (0%)</text>
20
-<text text-anchor="start" x="23.5" y="-115.2" font-family="Times,serif" font-size="16.00">Dropped 56 nodes (cum &lt;= 35600000ns)</text>
21
-<text text-anchor="start" x="23.5" y="-97.2" font-family="Times,serif" font-size="16.00">Showing top 2 nodes out of 38 (cum &gt;= 7070000000ns)</text>
22
-</g>
23
-<!-- N1 -->
24
-<g id="node2" class="node"><title>N1</title>
25
-<g id="a_node2"><a xlink:title="start_thread (7120000000ns)">
26
-<polygon fill="#f8f8f8" stroke="black" points="513,-155 413,-155 413,-119 513,-119 513,-155"/>
27
-<text text-anchor="middle" x="463" y="-139.6" font-family="Times,serif" font-size="8.00">start_thread</text>
28
-<text text-anchor="middle" x="463" y="-130.6" font-family="Times,serif" font-size="8.00">0 of 7120000000ns(100%)</text>
29
-</a>
30
-</g>
31
-</g>
32
-<!-- N2 -->
33
-<g id="node3" class="node"><title>N2</title>
34
-<g id="a_node3"><a xlink:title="RunWorkerLoop (7070000000ns)">
35
-<polygon fill="#f8f8f8" stroke="black" points="515.5,-36 410.5,-36 410.5,-0 515.5,-0 515.5,-36"/>
36
-<text text-anchor="middle" x="463" y="-20.6" font-family="Times,serif" font-size="8.00">RunWorkerLoop</text>
37
-<text text-anchor="middle" x="463" y="-11.6" font-family="Times,serif" font-size="8.00">0 of 7070000000ns(99.30%)</text>
38
-</a>
39
-</g>
40
-</g>
41
-<!-- N1&#45;&gt;N2 -->
42
-<g id="edge1" class="edge"><title>N1&#45;&gt;N2</title>
43
-<g id="a_edge1"><a xlink:title="start_thread ... RunWorkerLoop (7070000000ns)">
44
-<path fill="none" stroke="black" stroke-width="5" stroke-dasharray="1,5" d="M463,-118.987C463,-99.9242 463,-68.7519 463,-46.2768"/>
45
-<polygon fill="black" stroke="black" stroke-width="5" points="467.375,-46.0333 463,-36.0333 458.625,-46.0334 467.375,-46.0333"/>
46
-</a>
47
-</g>
48
-<g id="a_edge1&#45;label"><a xlink:title="start_thread ... RunWorkerLoop (7070000000ns)">
49
-<text text-anchor="middle" x="505" y="-58.3" font-family="Times,serif" font-size="14.00"> 7070000000ns</text>
50
-</a>
51
-</g>
52
-</g>
53
-</g>
54
-</g></svg>

+ 0
- 85
internal/driver/testdata/wrapper/addr2line 查看文件

1
-#!/bin/bash
2
-# Copyright 2014 Google Inc. All Rights Reserved.
3
-#
4
-# Licensed under the Apache License, Version 2.0 (the "License");
5
-# you may not use this file except in compliance with the License.
6
-# You may obtain a copy of the License at
7
-#
8
-#     http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-# Unless required by applicable law or agreed to in writing, software
11
-# distributed under the License is distributed on an "AS IS" BASIS,
12
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-# See the License for the specific language governing permissions and
14
-# limitations under the License.
15
-#
16
-# addr2line stub for testing of addr2liner.
17
-# Will recognize (and ignore) the -aiCfej options.
18
-#
19
-# Accepts addresses 1000 to 9000 and output multiple frames of the form:
20
-#   0x9000/fun9000/file9000:9000
21
-#   0x8000/fun8000/file8000:8000
22
-#   0x7000/fun7000/file7000:7000
23
-#   ...
24
-#   0x1000/fun1000/file1000:1000
25
-#
26
-# Returns ??/??/??:0 for all other inputs.
27
-
28
-while getopts aiCfe:j: opt; do
29
-  case "$opt" in
30
-    a|i|C|f|e|j) ;;
31
-    *)
32
-      echo "unrecognized option: $1" >&2
33
-      exit 1
34
-  esac
35
-done
36
-
37
-while read input
38
-do
39
-  address="$input"
40
-  
41
-  # remove 0x from input.
42
-  case "${address}" in
43
-    0x*)
44
-      address=$(printf '%x' "$address")
45
-      ;;
46
-    *)
47
-      address=$(printf '%x' "0x$address")
48
-  esac
49
-
50
-  printf '0x%x\n' "0x$address"
51
-  loop=1
52
-  while [ $loop -eq 1 ]
53
-  do
54
-    # prepare default output.
55
-    output2="fun${address}"
56
-    output3="file${address}:${address}"
57
-
58
-    # specialize output for selected cases.
59
-	  case "${address}" in
60
-      1000)
61
-        output2="_Z3fooid.clone2"
62
-        loop=0
63
-        ;;
64
-      2000)
65
-        output2="_ZNSaIiEC1Ev.clone18"
66
-        address=1000
67
-        ;;
68
-      3000)
69
-        output2="_ZNSt6vectorIS_IS_IiSaIiEESaIS1_EESaIS3_EEixEm"
70
-        address=2000
71
-        ;;
72
-      [4-9]000)
73
-        address=$(expr ${address} - 1000)
74
-        ;;
75
-      *)
76
-        output2='??'
77
-        output3='??:0'
78
-        loop=0
79
-    esac
80
-
81
-    echo "$output2"
82
-    echo "$output3"
83
-  done
84
-done
85
-exit 0

+ 0
- 29
internal/driver/testdata/wrapper/dot 查看文件

1
-#!/bin/bash
2
-# Copyright 2014 Google Inc. All Rights Reserved.
3
-#
4
-# Licensed under the Apache License, Version 2.0 (the "License");
5
-# you may not use this file except in compliance with the License.
6
-# You may obtain a copy of the License at
7
-#
8
-#     http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-# Unless required by applicable law or agreed to in writing, software
11
-# distributed under the License is distributed on an "AS IS" BASIS,
12
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-# See the License for the specific language governing permissions and
14
-# limitations under the License.
15
-
16
-case "$1" in
17
-  "-Tsvg" )
18
-	  if ! grep -q 'Type: cpu.*Duration: 10s' ; then
19
-	    echo "Couldn't recognize dot input" >&2
20
-      exit 1
21
-    fi
22
-	  cat testdata/cppbench.svg
23
-    exit 0
24
-    ;;
25
-  *       )
26
-    echo "Unexpected argument $1" >&2
27
-    exit 1
28
-    ;;
29
-esac

+ 0
- 62
internal/driver/testdata/wrapper/nm 查看文件

1
-#!/bin/bash
2
-# Copyright 2014 Google Inc. All Rights Reserved.
3
-#
4
-# Licensed under the Apache License, Version 2.0 (the "License");
5
-# you may not use this file except in compliance with the License.
6
-# You may obtain a copy of the License at
7
-#
8
-#     http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-# Unless required by applicable law or agreed to in writing, software
11
-# distributed under the License is distributed on an "AS IS" BASIS,
12
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-# See the License for the specific language governing permissions and
14
-# limitations under the License.
15
-#
16
-# nm stub for testing of listing.
17
-# Will recognize (and ignore) the -nC options.
18
-#
19
-# Outputs fixed nm output.
20
-
21
-while getopts nC opt; do
22
-  case "$opt" in
23
-    n) ;;
24
-    C) demangle=1;;
25
-    *)
26
-      echo "unrecognized option: $1" >&2
27
-      exit 1
28
-  esac
29
-done
30
-
31
-if [ $demangle ] 
32
-then
33
-  cat <<EOF
34
-0000000000001000 t lineA001
35
-0000000000001000 t lineA002
36
-0000000000001000 t line1000
37
-0000000000002000 t line200A
38
-0000000000002000 t line2000
39
-0000000000002000 t line200B
40
-0000000000003000 t line3000
41
-0000000000003000 t Dumb::operator()(char const*) const
42
-0000000000003000 t lineB00C
43
-0000000000003000 t line300D
44
-0000000000004000 t _the_end
45
-EOF
46
-  exit 0
47
-fi
48
-
49
-cat <<EOF
50
-0000000000001000 t lineA001
51
-0000000000001000 t lineA002
52
-0000000000001000 t line1000
53
-0000000000002000 t line200A
54
-0000000000002000 t line2000
55
-0000000000002000 t line200B
56
-0000000000003000 t line3000
57
-0000000000003000 t _ZNK4DumbclEPKc
58
-0000000000003000 t lineB00C
59
-0000000000003000 t line300D
60
-0000000000004000 t _the_end
61
-EOF
62
-exit 0

+ 0
- 59
internal/driver/testdata/wrapper/objdump 查看文件

1
-#!/bin/bash
2
-# Copyright 2014 Google Inc. All Rights Reserved.
3
-#
4
-# Licensed under the Apache License, Version 2.0 (the "License");
5
-# you may not use this file except in compliance with the License.
6
-# You may obtain a copy of the License at
7
-#
8
-#     http://www.apache.org/licenses/LICENSE-2.0
9
-#
10
-# Unless required by applicable law or agreed to in writing, software
11
-# distributed under the License is distributed on an "AS IS" BASIS,
12
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
-# See the License for the specific language governing permissions and
14
-# limitations under the License.
15
-#
16
-# objdump stub for testing of listing.
17
-# Will recognize (and ignore) the -nC options.
18
-#
19
-# Outputs fixed nm output.
20
-
21
-START=0
22
-STOP=0
23
-while [ $# -gt 1 ] ; do 
24
- case "$1" in 
25
-   --start-address=*) START=$(echo $1 | sed 's/.*=//') ;;
26
-   --stop-address=*) STOP=$(echo $1 | sed 's/.*=//') ;; 
27
-   --no-show-raw-insn|-d|-C|-n|-l) ;;
28
-   *) echo "Unrecognized option $1"
29
-     exit 1
30
- esac
31
- shift
32
-done
33
-
34
-case "$START$STOP" in 
35
-  "0x10000x1fff")
36
-  cat <<EOF
37
-  1000: instruction one
38
-  1001: instruction two
39
-  1002: instruction three
40
-  1003: instruction four
41
-EOF
42
-  ;;
43
-  "0x20000x2fff")
44
-  cat <<EOF
45
-  2000: instruction one
46
-  2001: instruction two
47
-EOF
48
-  ;;
49
-  "0x30000x3fff")
50
-  cat <<EOF
51
-  3000: instruction one
52
-  3001: instruction two
53
-  3002: instruction three
54
-  3003: instruction four
55
-  3004: instruction five
56
-EOF
57
-  ;;
58
-esac
59
-exit 0