|
@@ -177,14 +177,20 @@ func TestSetFastSymbolization(t *testing.T) {
|
177
|
177
|
|
178
|
178
|
func skipUnlessLinuxAmd64(t *testing.T) {
|
179
|
179
|
if runtime.GOOS != "linux" || runtime.GOARCH != "amd64" {
|
180
|
|
- t.Skip("Disasm only tested on x86-64 linux")
|
|
180
|
+ t.Skip("This test only works on x86-64 Linux")
|
|
181
|
+ }
|
|
182
|
+}
|
|
183
|
+
|
|
184
|
+func skipUnlessDarwinAmd64(t *testing.T) {
|
|
185
|
+ if runtime.GOOS != "darwin" || runtime.GOARCH != "amd64" {
|
|
186
|
+ t.Skip("This test only works on x86-64 Mac")
|
181
|
187
|
}
|
182
|
188
|
}
|
183
|
189
|
|
184
|
190
|
func TestDisasm(t *testing.T) {
|
185
|
191
|
skipUnlessLinuxAmd64(t)
|
186
|
192
|
bu := &Binutils{}
|
187
|
|
- insts, err := bu.Disasm(filepath.Join("testdata", "hello"), 0, math.MaxUint64)
|
|
193
|
+ insts, err := bu.Disasm(filepath.Join("testdata", "exe_linux_64"), 0, math.MaxUint64)
|
188
|
194
|
if err != nil {
|
189
|
195
|
t.Fatalf("Disasm: unexpected error %v", err)
|
190
|
196
|
}
|
|
@@ -199,6 +205,17 @@ func TestDisasm(t *testing.T) {
|
199
|
205
|
}
|
200
|
206
|
}
|
201
|
207
|
|
|
208
|
+func findSymbol(syms []*plugin.Sym, name string) *plugin.Sym {
|
|
209
|
+ for _, s := range syms {
|
|
210
|
+ for _, n := range s.Name {
|
|
211
|
+ if n == name {
|
|
212
|
+ return s
|
|
213
|
+ }
|
|
214
|
+ }
|
|
215
|
+ }
|
|
216
|
+ return nil
|
|
217
|
+}
|
|
218
|
+
|
202
|
219
|
func TestObjFile(t *testing.T) {
|
203
|
220
|
skipUnlessLinuxAmd64(t)
|
204
|
221
|
for _, tc := range []struct {
|
|
@@ -215,7 +232,7 @@ func TestObjFile(t *testing.T) {
|
215
|
232
|
} {
|
216
|
233
|
t.Run(tc.desc, func(t *testing.T) {
|
217
|
234
|
bu := &Binutils{}
|
218
|
|
- f, err := bu.Open(filepath.Join("testdata", "hello"), tc.start, tc.limit, tc.offset)
|
|
235
|
+ f, err := bu.Open(filepath.Join("testdata", "exe_linux_64"), tc.start, tc.limit, tc.offset)
|
219
|
236
|
if err != nil {
|
220
|
237
|
t.Fatalf("Open: unexpected error %v", err)
|
221
|
238
|
}
|
|
@@ -225,17 +242,7 @@ func TestObjFile(t *testing.T) {
|
225
|
242
|
t.Fatalf("Symbols: unexpected error %v", err)
|
226
|
243
|
}
|
227
|
244
|
|
228
|
|
- find := func(name string) *plugin.Sym {
|
229
|
|
- for _, s := range syms {
|
230
|
|
- for _, n := range s.Name {
|
231
|
|
- if n == name {
|
232
|
|
- return s
|
233
|
|
- }
|
234
|
|
- }
|
235
|
|
- }
|
236
|
|
- return nil
|
237
|
|
- }
|
238
|
|
- m := find("main")
|
|
245
|
+ m := findSymbol(syms, "main")
|
239
|
246
|
if m == nil {
|
240
|
247
|
t.Fatalf("Symbols: did not find main")
|
241
|
248
|
}
|
|
@@ -255,6 +262,65 @@ func TestObjFile(t *testing.T) {
|
255
|
262
|
}
|
256
|
263
|
}
|
257
|
264
|
|
|
265
|
+func TestMachoFiles(t *testing.T) {
|
|
266
|
+ skipUnlessDarwinAmd64(t)
|
|
267
|
+
|
|
268
|
+ t.Skip("Disabled because of issues with addr2line (see https://github.com/google/pprof/pull/313#issuecomment-364073010)")
|
|
269
|
+
|
|
270
|
+ // Load `file`, pretending it was mapped at `start`. Then get the symbol
|
|
271
|
+ // table. Check that it contains the symbol `sym` and that the address
|
|
272
|
+ // `addr` gives the `expected` stack trace.
|
|
273
|
+ for _, tc := range []struct {
|
|
274
|
+ desc string
|
|
275
|
+ file string
|
|
276
|
+ start, limit, offset uint64
|
|
277
|
+ addr uint64
|
|
278
|
+ sym string
|
|
279
|
+ expected []plugin.Frame
|
|
280
|
+ }{
|
|
281
|
+ {"normal mapping", "exe_mac_64", 0x100000000, math.MaxUint64, 0,
|
|
282
|
+ 0x100000f50, "_main",
|
|
283
|
+ []plugin.Frame{
|
|
284
|
+ {Func: "main", File: "/tmp/hello.c", Line: 3},
|
|
285
|
+ }},
|
|
286
|
+ {"other mapping", "exe_mac_64", 0x200000000, math.MaxUint64, 0,
|
|
287
|
+ 0x200000f50, "_main",
|
|
288
|
+ []plugin.Frame{
|
|
289
|
+ {Func: "main", File: "/tmp/hello.c", Line: 3},
|
|
290
|
+ }},
|
|
291
|
+ {"lib normal mapping", "lib_mac_64", 0, math.MaxUint64, 0,
|
|
292
|
+ 0xfa0, "_bar",
|
|
293
|
+ []plugin.Frame{
|
|
294
|
+ {Func: "bar", File: "/tmp/lib.c", Line: 6},
|
|
295
|
+ }},
|
|
296
|
+ } {
|
|
297
|
+ t.Run(tc.desc, func(t *testing.T) {
|
|
298
|
+ bu := &Binutils{}
|
|
299
|
+ f, err := bu.Open(filepath.Join("testdata", tc.file), tc.start, tc.limit, tc.offset)
|
|
300
|
+ if err != nil {
|
|
301
|
+ t.Fatalf("Open: unexpected error %v", err)
|
|
302
|
+ }
|
|
303
|
+ defer f.Close()
|
|
304
|
+ syms, err := f.Symbols(nil, 0)
|
|
305
|
+ if err != nil {
|
|
306
|
+ t.Fatalf("Symbols: unexpected error %v", err)
|
|
307
|
+ }
|
|
308
|
+
|
|
309
|
+ m := findSymbol(syms, tc.sym)
|
|
310
|
+ if m == nil {
|
|
311
|
+ t.Fatalf("Symbols: could not find symbol %v", tc.sym)
|
|
312
|
+ }
|
|
313
|
+ gotFrames, err := f.SourceLine(tc.addr)
|
|
314
|
+ if err != nil {
|
|
315
|
+ t.Fatalf("SourceLine: unexpected error %v", err)
|
|
316
|
+ }
|
|
317
|
+ if !reflect.DeepEqual(gotFrames, tc.expected) {
|
|
318
|
+ t.Fatalf("SourceLine for main: got %v; want %v\n", gotFrames, tc.expected)
|
|
319
|
+ }
|
|
320
|
+ })
|
|
321
|
+ }
|
|
322
|
+}
|
|
323
|
+
|
258
|
324
|
func TestLLVMSymbolizer(t *testing.T) {
|
259
|
325
|
if runtime.GOOS != "linux" {
|
260
|
326
|
t.Skip("testtdata/llvm-symbolizer has only been tested on linux")
|