瀏覽代碼

Merge pull request #41 from aalexand/aalexand/unsource-url-mappings

Reset mapping file to empty string if it was patched to be the source URL
Raul Silvera 8 年之前
父節點
當前提交
246c174d3e
共有 3 個文件被更改,包括 85 次插入0 次删除
  1. 15
    0
      internal/driver/fetch.go
  2. 62
    0
      internal/driver/fetch_test.go
  3. 8
    0
      internal/symbolizer/symbolizer.go

+ 15
- 0
internal/driver/fetch.go 查看文件

@@ -72,6 +72,7 @@ func fetchProfiles(s *source, o *plugin.Options) (*profile.Profile, error) {
72 72
 		return nil, err
73 73
 	}
74 74
 	p.RemoveUninteresting()
75
+	unsourceMappings(p)
75 76
 
76 77
 	// Save a copy of the merged profile if there is at least one remote source.
77 78
 	if save {
@@ -283,6 +284,8 @@ func collectMappingSources(p *profile.Profile, source string) plugin.MappingSour
283 284
 			// If there is no build id or source file, use the source as the
284 285
 			// mapping file. This will enable remote symbolization for this
285 286
 			// mapping, in particular for Go profiles on the legacy format.
287
+			// The source is reset back to empty string by unsourceMapping
288
+			// which is called after symbolization is finished.
286 289
 			m.File = source
287 290
 			key = source
288 291
 		}
@@ -291,6 +294,18 @@ func collectMappingSources(p *profile.Profile, source string) plugin.MappingSour
291 294
 	return ms
292 295
 }
293 296
 
297
+// unsourceMappings iterates over the mappings in a profile and replaces file
298
+// set to the remote source URL by collectMappingSources back to empty string.
299
+func unsourceMappings(p *profile.Profile) {
300
+	for _, m := range p.Mapping {
301
+		if m.BuildID == "" {
302
+			if u, err := url.Parse(m.File); err == nil && u.IsAbs() {
303
+				m.File = ""
304
+			}
305
+		}
306
+	}
307
+}
308
+
294 309
 // locateBinaries searches for binary files listed in the profile and, if found,
295 310
 // updates the profile accordingly.
296 311
 func locateBinaries(p *profile.Profile, s *source, obj plugin.ObjTool, ui plugin.UI) {

+ 62
- 0
internal/driver/fetch_test.go 查看文件

@@ -21,6 +21,7 @@ import (
21 21
 	"net/url"
22 22
 	"os"
23 23
 	"path/filepath"
24
+	"reflect"
24 25
 	"regexp"
25 26
 	"testing"
26 27
 	"time"
@@ -76,6 +77,55 @@ func TestSymbolizationPath(t *testing.T) {
76 77
 	os.Setenv("PPROF_BINARY_PATH", savePath)
77 78
 }
78 79
 
80
+func TestCollectMappingSources(t *testing.T) {
81
+	const startAddress uint64 = 0x40000
82
+	const url = "http://example.com"
83
+	for _, tc := range []struct {
84
+		file, buildID string
85
+		want          plugin.MappingSources
86
+	}{
87
+		{"/usr/bin/binary", "buildId", mappingSources("buildId", url, startAddress)},
88
+		{"/usr/bin/binary", "", mappingSources("/usr/bin/binary", url, startAddress)},
89
+		{"", "", mappingSources(url, url, startAddress)},
90
+	} {
91
+		p := &profile.Profile{
92
+			Mapping: []*profile.Mapping{
93
+				{
94
+					File:    tc.file,
95
+					BuildID: tc.buildID,
96
+					Start:   startAddress,
97
+				},
98
+			},
99
+		}
100
+		got := collectMappingSources(p, url)
101
+		if !reflect.DeepEqual(got, tc.want) {
102
+			t.Errorf("%s:%s, want %s, got %s", tc.file, tc.buildID, tc.want, got)
103
+		}
104
+	}
105
+}
106
+
107
+func TestUnsourceMappings(t *testing.T) {
108
+	for _, tc := range []struct {
109
+		file, buildID, want string
110
+	}{
111
+		{"/usr/bin/binary", "buildId", "/usr/bin/binary"},
112
+		{"http://example.com", "", ""},
113
+	} {
114
+		p := &profile.Profile{
115
+			Mapping: []*profile.Mapping{
116
+				{
117
+					File:    tc.file,
118
+					BuildID: tc.buildID,
119
+				},
120
+			},
121
+		}
122
+		unsourceMappings(p)
123
+		if got := p.Mapping[0].File; got != tc.want {
124
+			t.Errorf("%s:%s, want %s, got %s", tc.file, tc.buildID, tc.want, got)
125
+		}
126
+	}
127
+}
128
+
79 129
 type testObj struct {
80 130
 	home string
81 131
 }
@@ -125,6 +175,18 @@ func TestFetch(t *testing.T) {
125 175
 	}
126 176
 }
127 177
 
178
+// mappingSources creates MappingSources map with a single item.
179
+func mappingSources(key, source string, start uint64) plugin.MappingSources {
180
+	return plugin.MappingSources{
181
+		key: []struct {
182
+			Source string
183
+			Start  uint64
184
+		}{
185
+			{Source: source, Start: start},
186
+		},
187
+	}
188
+}
189
+
128 190
 // stubHTTPGet intercepts a call to http.Get and rewrites it to use
129 191
 // "file://" to get the profile directly from a file.
130 192
 func stubHTTPGet(source string, _ time.Duration) (*http.Response, error) {

+ 8
- 0
internal/symbolizer/symbolizer.go 查看文件

@@ -21,6 +21,7 @@ import (
21 21
 	"fmt"
22 22
 	"io/ioutil"
23 23
 	"net/http"
24
+	"net/url"
24 25
 	"path/filepath"
25 26
 	"strings"
26 27
 
@@ -299,6 +300,13 @@ func newMapping(prof *profile.Profile, obj plugin.ObjTool, ui plugin.UI, force b
299 300
 			continue
300 301
 		}
301 302
 
303
+		// Skip mappings pointing to a source URL
304
+		if m.BuildID == "" {
305
+			if u, err := url.Parse(m.File); err == nil && u.IsAbs() {
306
+				continue
307
+			}
308
+		}
309
+
302 310
 		f, err := obj.Open(m.File, m.Start, m.Limit, m.Offset)
303 311
 		if err != nil {
304 312
 			ui.PrintErr("Local symbolization failed for ", name, ": ", err)