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