1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package main
19
20 import (
21 "bufio"
22 "flag"
23 "fmt"
24 "log"
25 "os"
26 "strconv"
27 "strings"
28
29 "cmd/internal/objfile"
30 )
31
32 func printUsage(w *os.File) {
33 fmt.Fprintf(w, "usage: addr2line binary\n")
34 fmt.Fprintf(w, "reads addresses from standard input and writes two lines for each:\n")
35 fmt.Fprintf(w, "\tfunction name\n")
36 fmt.Fprintf(w, "\tfile:line\n")
37 }
38
39 func usage() {
40 printUsage(os.Stderr)
41 os.Exit(2)
42 }
43
44 func main() {
45 log.SetFlags(0)
46 log.SetPrefix("addr2line: ")
47
48
49 if len(os.Args) > 1 && os.Args[1] == "--help" {
50 printUsage(os.Stdout)
51 os.Exit(0)
52 }
53
54 flag.Usage = usage
55 flag.Parse()
56 if flag.NArg() != 1 {
57 usage()
58 }
59
60 f, err := objfile.Open(flag.Arg(0))
61 if err != nil {
62 log.Fatal(err)
63 }
64 defer f.Close()
65
66 tab, err := f.PCLineTable()
67 if err != nil {
68 log.Fatalf("reading %s: %v", flag.Arg(0), err)
69 }
70
71 stdin := bufio.NewScanner(os.Stdin)
72 stdout := bufio.NewWriter(os.Stdout)
73
74 for stdin.Scan() {
75 p := stdin.Text()
76 if strings.Contains(p, ":") {
77
78
79
80
81 fmt.Fprintf(stdout, "!reverse translation not implemented\n")
82 continue
83 }
84 pc, _ := strconv.ParseUint(strings.TrimPrefix(p, "0x"), 16, 64)
85 file, line, fn := tab.PCToLine(pc)
86 name := "?"
87 if fn != nil {
88 name = fn.Name
89 } else {
90 file = "?"
91 line = 0
92 }
93 fmt.Fprintf(stdout, "%s\n%s:%d\n", name, file, line)
94 }
95 stdout.Flush()
96 }
97
View as plain text