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  }