github.com/searKing/golang/go@v1.2.117/runtime/extern.go (about) 1 package runtime 2 3 import ( 4 "path" 5 "runtime" 6 "strings" 7 ) 8 9 // GetCallerPC returns the caller PC of the function that calls it. 10 // The argument skip is the number of stack frames 11 // to skip before recording in pc, with 0 identifying the frame for Callers itself and 12 // 1 identifying the caller of Callers. 13 func GetCallerPC(skip int) uintptr { 14 var pcs [1]uintptr 15 runtime.Callers(skip+1, pcs[:]) 16 return pcs[0] 17 } 18 19 // GetCallerFrame returns the caller frame of the function that calls it. 20 // The argument skip is the number of stack frames 21 // to skip before recording in pc, with 0 identifying the frame for Callers itself and 22 // 1 identifying the caller of Callers. 23 func GetCallerFrame(skip int) *runtime.Frame { 24 var pcs [1]uintptr 25 n := runtime.Callers(skip+1, pcs[:]) 26 if n < 1 { 27 return nil 28 } 29 frame, _ := runtime.CallersFrames(pcs[:]).Next() 30 return &frame 31 } 32 33 // GetCaller returns the caller of the function that calls it. 34 // The argument skip is the number of stack frames 35 // to skip before recording in pc, with 0 identifying the frame for Callers itself and 36 // 1 identifying the caller of Callers. 37 func GetCaller(skip int) string { 38 var pc [1]uintptr 39 runtime.Callers(skip+1, pc[:]) 40 41 f := runtime.FuncForPC(pc[0]) 42 if f == nil { 43 return "???" 44 } 45 return f.Name() 46 } 47 48 // GetShortCaller returns the short form of GetCaller. 49 // The argument skip is the number of stack frames 50 // to skip before recording in pc, with 0 identifying the frame for Callers itself and 51 // 1 identifying the caller of Callers. 52 func GetShortCaller(skip int) string { 53 return strings.TrimPrefix(path.Ext(GetCaller(skip+1)), ".") 54 } 55 56 // GetCallerFuncFileLine returns the __FUNCTION__, __FILE__ and __LINE__ of the function that calls it. 57 // The argument skip is the number of stack frames 58 // to skip before recording in pc, with 0 identifying the frame for Callers itself and 59 // 1 identifying the caller of Callers. 60 func GetCallerFuncFileLine(skip int) (caller string, file string, line int) { 61 var ok bool 62 // For historical reasons the meaning of skip differs between Caller and Callers 63 pc, file, line, ok := runtime.Caller(skip) 64 if !ok { 65 caller = "???" 66 file = "???" 67 line = 0 68 return 69 } 70 f := runtime.FuncForPC(pc) 71 if f != nil { 72 caller = f.Name() 73 return 74 } 75 caller = "???" 76 return 77 } 78 79 // GetShortCallerFuncFileLine returns the short form of GetCallerFuncFileLine. 80 // The argument skip is the number of stack frames 81 // to skip before recording in pc, with 0 identifying the frame for Callers itself and 82 // 1 identifying the caller of Callers. 83 func GetShortCallerFuncFileLine(skip int) (caller string, file string, line int) { 84 caller, file, line = GetCallerFuncFileLine(skip + 1) 85 return strings.TrimPrefix(path.Ext(caller), "."), path.Base(file), line 86 } 87 88 // GetCallStack Same as stdlib http server code. Manually allocate stack trace buffer size 89 // to prevent excessively large logs 90 func GetCallStack(size int) string { 91 buf := make([]byte, size) 92 stk := string(buf[:runtime.Stack(buf[:], false)]) 93 lines := strings.Split(stk, "\n") 94 if len(lines) < 3 { 95 return stk 96 } 97 98 // trim GetCallStack 99 var stackLines []string 100 stackLines = append(stackLines, lines[0]) 101 stackLines = append(stackLines, lines[3:]...) 102 103 return strings.Join(stackLines, "\n") 104 }