(t *testing.T)
| 382 | } |
| 383 | |
| 384 | func TestMachoFiles(t *testing.T) { |
| 385 | // If this test fails, check the address for main function in testdata/exe_mac_64 |
| 386 | // and testdata/lib_mac_64 using addr2line or gaddr2line. Update the |
| 387 | // hardcoded addresses below to match the addresses from the output. |
| 388 | skipUnlessDarwinAmd64(t) |
| 389 | |
| 390 | // Load `file`, pretending it was mapped at `start`. Then get the symbol |
| 391 | // table. Check that it contains the symbol `sym` and that the address |
| 392 | // `addr` gives the `expected` stack trace. |
| 393 | for _, tc := range []struct { |
| 394 | desc string |
| 395 | file string |
| 396 | start, limit, offset uint64 |
| 397 | addr uint64 |
| 398 | sym string |
| 399 | expected []plugin.Frame |
| 400 | }{ |
| 401 | {"normal mapping", "exe_mac_64", 0x100000000, math.MaxUint64, 0, |
| 402 | 0x100000f50, "_main", |
| 403 | []plugin.Frame{ |
| 404 | {Func: "main", File: "/tmp/hello.c", Line: 3, StartLine: 3}, |
| 405 | }}, |
| 406 | {"other mapping", "exe_mac_64", 0x200000000, math.MaxUint64, 0, |
| 407 | 0x200000f50, "_main", |
| 408 | []plugin.Frame{ |
| 409 | {Func: "main", File: "/tmp/hello.c", Line: 3, StartLine: 3}, |
| 410 | }}, |
| 411 | {"lib normal mapping", "lib_mac_64", 0, math.MaxUint64, 0, |
| 412 | 0xfa0, "_bar", |
| 413 | []plugin.Frame{ |
| 414 | {Func: "bar", File: "/tmp/lib.c", Line: 5, StartLine: 5}, |
| 415 | }}, |
| 416 | } { |
| 417 | t.Run(tc.desc, func(t *testing.T) { |
| 418 | bu := &Binutils{} |
| 419 | f, err := bu.Open(filepath.Join("testdata", tc.file), tc.start, tc.limit, tc.offset, "") |
| 420 | if err != nil { |
| 421 | t.Fatalf("Open: unexpected error %v", err) |
| 422 | } |
| 423 | t.Logf("binutils: %v", bu) |
| 424 | if runtime.GOOS == "darwin" && !bu.rep.addr2lineFound && !bu.rep.llvmSymbolizerFound { |
| 425 | // On macOS, user needs to install gaddr2line or llvm-symbolizer with |
| 426 | // Homebrew, skip the test when the environment doesn't have it |
| 427 | // installed. |
| 428 | t.Skip("couldn't find addr2line or gaddr2line") |
| 429 | } |
| 430 | defer f.Close() |
| 431 | syms, err := f.Symbols(nil, 0) |
| 432 | if err != nil { |
| 433 | t.Fatalf("Symbols: unexpected error %v", err) |
| 434 | } |
| 435 | |
| 436 | m := findSymbol(syms, tc.sym) |
| 437 | if m == nil { |
| 438 | t.Fatalf("Symbols: could not find symbol %v", tc.sym) |
| 439 | } |
| 440 | gotFrames, err := f.SourceLine(tc.addr) |
| 441 | if err != nil { |
nothing calls this directly
no test coverage detected
searching dependent graphs…