github.com/podhmo/reflect-shape@v0.4.3/metadata/internal/unsaferuntime/api.go (about) 1 package unsaferuntime 2 3 import ( 4 "fmt" 5 "runtime" 6 "strings" 7 "unsafe" 8 ) 9 10 type Accessor struct { 11 // TODO: cache 12 // fmPCtoPC map[uintptr]uintptr 13 } 14 15 func New() *Accessor { 16 return &Accessor{} 17 } 18 19 func (a *Accessor) FuncForPC(pc uintptr) *runtime.Func { 20 rfunc := runtime.FuncForPC(pc) 21 if !strings.HasSuffix(rfunc.Name(), "-fm") { 22 return rfunc 23 } 24 target := strings.TrimSuffix(rfunc.Name(), "-fm") 25 26 var prevs []*moduledata 27 findDepth := 1 28 for datap := &runtime_firstmoduledata; datap != nil; datap = datap.next { 29 if datap.minpc <= pc && pc < datap.maxpc { 30 m := datap 31 for _, functab := range m.ftab { 32 // fmt.Printf("functab: %x, %x\n", functab.entryoff, functab.funcoff) 33 funcoff := functab.funcoff 34 rfunc := (*runtime.Func)(unsafe.Pointer(&m.pclntable[funcoff])) 35 if rfunc.Name() == target { 36 return rfunc 37 } 38 } 39 // find prev 40 if len(prevs) > 0 { 41 m := prevs[len(prevs)-findDepth] 42 for _, functab := range m.ftab { 43 // fmt.Printf("functab: %x, %x\n", functab.entryoff, functab.funcoff) 44 funcoff := functab.funcoff 45 rfunc := (*runtime.Func)(unsafe.Pointer(&m.pclntable[funcoff])) 46 if rfunc.Name() == target { 47 return rfunc 48 } 49 } 50 findDepth++ 51 } 52 // find next 53 continue 54 } 55 prevs = append(prevs, datap) 56 } 57 return nil 58 } 59 60 func Print(pc uintptr, pkg string) error { 61 prefix := strings.TrimSuffix(pkg, ".") + "." 62 63 for datap := &runtime_firstmoduledata; datap != nil; datap = datap.next { 64 if datap.minpc <= pc && pc < datap.maxpc { 65 m := datap 66 for _, functab := range m.ftab { 67 // fmt.Printf("functab: %x, %x\n", functab.entryoff, functab.funcoff) 68 funcoff := functab.funcoff 69 rfunc := (*runtime.Func)(unsafe.Pointer(&m.pclntable[funcoff])) 70 71 if strings.Contains(rfunc.Name(), prefix) { 72 filename, lineno := rfunc.FileLine(rfunc.Entry()) 73 fmt.Printf("* %s\t%v:%v\n", rfunc.Name(), filename, lineno) 74 } 75 } 76 } 77 } 78 79 return nil 80 }