소스 검색

Ensure symbolz is called after local symbolization

Even after local symbolization completes successfully we should
call remote symbolization in case there are some mapping that couldn't
be symbolized otherwise.

Add some tests to ensure both local and symbolz symbolization are called.
Raul Silvera 8 년 전
부모
커밋
3f456ae43b
2개의 변경된 파일72개의 추가작업 그리고 8개의 파일을 삭제
  1. 9
    5
      internal/symbolizer/symbolizer.go
  2. 63
    3
      internal/symbolizer/symbolizer_test.go

+ 9
- 5
internal/symbolizer/symbolizer.go 파일 보기

38
 	UI  plugin.UI
38
 	UI  plugin.UI
39
 }
39
 }
40
 
40
 
41
+// test taps for dependency injection
42
+var symbolzSymbolize = symbolz.Symbolize
43
+var localSymbolize = doLocalSymbolize
44
+
41
 // Symbolize attempts to symbolize profile p. First uses binutils on
45
 // Symbolize attempts to symbolize profile p. First uses binutils on
42
 // local binaries; if the source is a URL it attempts to get any
46
 // local binaries; if the source is a URL it attempts to get any
43
 // missed entries using symbolz.
47
 // missed entries using symbolz.
70
 	var err error
74
 	var err error
71
 	if local {
75
 	if local {
72
 		// Symbolize locally using binutils.
76
 		// Symbolize locally using binutils.
73
-		if err = localSymbolize(mode, p, s.Obj, s.UI); err == nil {
74
-			remote = false // Already symbolized, no need to apply remote symbolization.
77
+		if err = localSymbolize(mode, p, s.Obj, s.UI); err != nil {
78
+			s.UI.PrintErr("local symbolization: " + err.Error())
75
 		}
79
 		}
76
 	}
80
 	}
77
 	if remote {
81
 	if remote {
78
-		if err = symbolz.Symbolize(sources, postURL, p, s.UI); err != nil {
82
+		if err = symbolzSymbolize(sources, postURL, p, s.UI); err != nil {
79
 			return err // Ran out of options.
83
 			return err // Ran out of options.
80
 		}
84
 		}
81
 	}
85
 	}
97
 	return ioutil.ReadAll(resp.Body)
101
 	return ioutil.ReadAll(resp.Body)
98
 }
102
 }
99
 
103
 
100
-// localSymbolize adds symbol and line number information to all locations
104
+// doLocalSymbolize adds symbol and line number information to all locations
101
 // in a profile. mode enables some options to control
105
 // in a profile. mode enables some options to control
102
 // symbolization.
106
 // symbolization.
103
-func localSymbolize(mode string, prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI) error {
107
+func doLocalSymbolize(mode string, prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI) error {
104
 	force := false
108
 	force := false
105
 	// Disable some mechanisms based on mode string.
109
 	// Disable some mechanisms based on mode string.
106
 	for _, o := range strings.Split(strings.ToLower(mode), ":") {
110
 	for _, o := range strings.Split(strings.ToLower(mode), ":") {

+ 63
- 3
internal/symbolizer/symbolizer_test.go 파일 보기

17
 import (
17
 import (
18
 	"fmt"
18
 	"fmt"
19
 	"regexp"
19
 	"regexp"
20
+	"strings"
20
 	"testing"
21
 	"testing"
21
 
22
 
22
 	"github.com/google/pprof/internal/plugin"
23
 	"github.com/google/pprof/internal/plugin"
95
 }
96
 }
96
 
97
 
97
 func TestSymbolization(t *testing.T) {
98
 func TestSymbolization(t *testing.T) {
98
-	prof := testProfile
99
+	sSym := symbolzSymbolize
100
+	lSym := localSymbolize
101
+	defer func() {
102
+		symbolzSymbolize = sSym
103
+		localSymbolize = lSym
104
+	}()
105
+	symbolzSymbolize = symbolzMock
106
+	localSymbolize = localMock
107
+
108
+	type testcase struct {
109
+		mode        string
110
+		wantComment string
111
+	}
112
+
113
+	s := Symbolizer{
114
+		mockObjTool{},
115
+		&proftest.TestUI{T: t},
116
+	}
117
+	for i, tc := range []testcase{
118
+		{
119
+			"local",
120
+			"local=local",
121
+		},
122
+		{
123
+			"fastlocal",
124
+			"local=fastlocal",
125
+		},
126
+		{
127
+			"remote",
128
+			"symbolz",
129
+		},
130
+		{
131
+			"",
132
+			"local=:symbolz",
133
+		},
134
+	} {
135
+		prof := testProfile.Copy()
136
+		if err := s.Symbolize(tc.mode, nil, prof); err != nil {
137
+			t.Errorf("symbolize #%d: %v", i, err)
138
+			continue
139
+		}
140
+		if got, want := strings.Join(prof.Comments, ":"), tc.wantComment; got != want {
141
+			t.Errorf("got %s, want %s", got, want)
142
+			continue
143
+		}
144
+	}
145
+}
146
+
147
+func symbolzMock(sources plugin.MappingSources, syms func(string, string) ([]byte, error), p *profile.Profile, ui plugin.UI) error {
148
+	p.Comments = append(p.Comments, "symbolz")
149
+	return nil
150
+}
151
+
152
+func localMock(mode string, p *profile.Profile, obj plugin.ObjTool, ui plugin.UI) error {
153
+	p.Comments = append(p.Comments, "local="+mode)
154
+	return nil
155
+}
156
+
157
+func TestLocalSymbolization(t *testing.T) {
158
+	prof := testProfile.Copy()
99
 
159
 
100
 	if prof.HasFunctions() {
160
 	if prof.HasFunctions() {
101
 		t.Error("unexpected function names")
161
 		t.Error("unexpected function names")
105
 	}
165
 	}
106
 
166
 
107
 	b := mockObjTool{}
167
 	b := mockObjTool{}
108
-	if err := localSymbolize("", &prof, b, &proftest.TestUI{T: t}); err != nil {
109
-		t.Fatalf("Symbolize(): %v", err)
168
+	if err := localSymbolize("", prof, b, &proftest.TestUI{T: t}); err != nil {
169
+		t.Fatalf("localSymbolize(): %v", err)
110
 	}
170
 	}
111
 
171
 
112
 	for _, loc := range prof.Location {
172
 	for _, loc := range prof.Location {