github.com/PandaGoAdmin/utils@v0.0.0-20211208134815-d5461603a00f/debug.go (about) 1 package kgo 2 3 import ( 4 "fmt" 5 "go/parser" 6 "go/token" 7 "path/filepath" 8 "reflect" 9 "runtime" 10 "strings" 11 ) 12 13 // DumpPrint 打印调试变量. 14 func (ks *LkkDebug) DumpPrint(vs ...interface{}) { 15 dumpPrint(vs...) 16 } 17 18 // DumpStacks 打印堆栈信息. 19 func (kd *LkkDebug) DumpStacks() { 20 buf := make([]byte, 16384) 21 buf = buf[:runtime.Stack(buf, true)] 22 fmt.Printf("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===\n\n", buf) 23 } 24 25 // GetCallName 获取调用的方法名称;f为目标方法;onlyFun为true时仅返回方法,不包括包名. 26 func (kd *LkkDebug) GetCallName(f interface{}, onlyFun bool) string { 27 var funcObj *runtime.Func 28 r := reflectPtr(reflect.ValueOf(f)) 29 switch r.Kind() { 30 case reflect.Invalid: 31 // Skip this function, and fetch the PC and file for its parent 32 pc, _, _, _ := runtime.Caller(1) 33 // Retrieve a Function object this functions parent 34 funcObj = runtime.FuncForPC(pc) 35 case reflect.Func: 36 funcObj = runtime.FuncForPC(r.Pointer()) 37 default: 38 return "" 39 } 40 41 name := funcObj.Name() 42 if onlyFun { 43 // extract just the function name (and not the module path) 44 return strings.TrimPrefix(filepath.Ext(name), ".") 45 } 46 47 return name 48 } 49 50 // GetCallFile 获取调用方法的文件路径. 51 func (kd *LkkDebug) GetCallFile() string { 52 _, file, _, _ := runtime.Caller(1) 53 return file 54 } 55 56 // GetCallDir 获取调用方法的文件目录. 57 func (kd *LkkDebug) GetCallDir() string { 58 return filepath.Dir(kd.GetCallFile()) 59 } 60 61 // GetCallLine 获取调用方法的行号. 62 func (kd *LkkDebug) GetCallLine() int { 63 // Skip this function, and fetch the PC and file for its parent 64 _, _, line, _ := runtime.Caller(1) 65 return line 66 } 67 68 // GetCallPackage 获取调用方法或调用文件的包名.callFile为调用文件路径. 69 func (kd *LkkDebug) GetCallPackage(callFile ...string) string { 70 var sourceFile string 71 if len(callFile) == 0 { 72 sourceFile = kd.GetCallFile() 73 } else { 74 sourceFile = callFile[0] 75 } 76 77 fset := token.NewFileSet() 78 astFile, err := parser.ParseFile(fset, sourceFile, nil, parser.PackageClauseOnly) 79 if err != nil || astFile.Name == nil { 80 return "" 81 } 82 83 return astFile.Name.Name 84 } 85 86 // HasMethod 检查对象t是否具有method方法. 87 func (kd *LkkDebug) HasMethod(t interface{}, method string) bool { 88 _, err := methodExists(t, method) 89 return err == nil 90 } 91 92 // GetMethod 获取对象t中的method方法. 93 // 注意:返回的方法中的第一个参数是接收者. 94 // 所以,调用返回的方法时,必须将接收者作为第一个参数传递. 95 func (kd *LkkDebug) GetMethod(t interface{}, method string) interface{} { 96 return getMethod(t, method) 97 } 98 99 // CallMethod 调用对象的方法. 100 // 若执行成功,则结果是该方法的返回结果; 101 // 否则返回(nil, error). 102 func (kd *LkkDebug) CallMethod(t interface{}, method string, args ...interface{}) ([]interface{}, error) { 103 m := kd.GetMethod(t, method) 104 if m == nil { 105 return nil, fmt.Errorf("[CallMethod] The %#v have no method: %s", t, method) 106 } 107 108 return CallFunc(m, args...) 109 } 110 111 // GetFuncNames 获取变量的所有(公开的)函数名. 112 func (kd *LkkDebug) GetFuncNames(obj interface{}) (res []string) { 113 return getFuncNames(obj) 114 }