gitee.com/quant1x/gox@v1.21.2/runtime/stdlib.go (about)

     1  package runtime
     2  
     3  import (
     4  	"reflect"
     5  	"runtime"
     6  	_ "unsafe"
     7  )
     8  
     9  const (
    10  	invalidProgramCounters = 0
    11  	invalidFunctionName    = "<invalid runtimeFunctionForPC>"
    12  	unknownFilename        = "<unknown file>"
    13  	unknownLine            = -1
    14  )
    15  
    16  // Caller 获取正在运行的函数名, 文件名以及行号
    17  func Caller() (function, file string, line int) {
    18  	pcs := make([]uintptr, 1)
    19  	runtime.Callers(2, pcs)
    20  	pc := pcs[0]
    21  	return FuncInfo(pc)
    22  }
    23  
    24  //go:linkname runtimeFunctionForPC runtime.FuncForPC
    25  func runtimeFunctionForPC(pc uintptr) *runtime.Func
    26  
    27  // 获取pc
    28  func programCounters(v any) uintptr {
    29  	value := reflect.ValueOf(v)
    30  	var pc uintptr
    31  	if value.Kind() == reflect.Func {
    32  		pc = value.Pointer()
    33  	} else if value.Kind() == reflect.Uintptr {
    34  		pc = v.(uintptr)
    35  	} else {
    36  		pc = invalidProgramCounters
    37  	}
    38  	return pc
    39  }
    40  
    41  // FuncInfo 获取函数信息
    42  //
    43  //	v 接收func类型和uintptr
    44  func FuncInfo(v any) (nameOfFunction, filename string, lineNumber int) {
    45  	pc := programCounters(v)
    46  	if pc == invalidProgramCounters {
    47  		return invalidFunctionName, unknownFilename, unknownLine
    48  	}
    49  	f := runtimeFunctionForPC(pc)
    50  	if f == nil {
    51  		return invalidFunctionName, unknownFilename, unknownLine
    52  	}
    53  	nameOfFunction = f.Name()
    54  	filename, lineNumber = f.FileLine(pc)
    55  	return
    56  }
    57  
    58  // FuncName 获取函数名
    59  func FuncName(v any) (nameOfFunction string) {
    60  	pc := programCounters(v)
    61  	if pc == invalidProgramCounters {
    62  		return invalidFunctionName
    63  	}
    64  	f := runtimeFunctionForPC(pc)
    65  	if f == nil {
    66  		return invalidFunctionName
    67  	}
    68  	return f.Name()
    69  }