スキップが0である場合、この関数は、現在の通話発信機能、ファイル、プログラムカウンタPC、1名がレイヤ機能である、というように返します。
func Caller(skip int) (pc uintptr, file string, line int, ok bool)
例
package main
import (
"log"
"runtime"
)
func main() {
test()
}
func test() {
test2()
}
func test2() {
// 上2层函数信息
pc, file, line, ok := runtime.Caller(2)
// 是否获取成功
log.Println(ok)
// 函数指针
log.Println(pc)
// 所属文件
log.Println(file)
// 所属行
log.Println(line)
// 获取函数信息
f := runtime.FuncForPC(pc)
// 函数名
log.Println(f.Name())
// 当前函数信息
pc, file, line, ok = runtime.Caller(0)
log.Println(pc)
log.Println(file)
log.Println(line)
log.Println(ok)
f = runtime.FuncForPC(pc)
log.Println(f.Name())
// 上一层函数信息
pc, file, line, ok = runtime.Caller(1)
log.Println(pc)
log.Println(file)
log.Println(line)
log.Println(ok)
f = runtime.FuncForPC(pc)
log.Println(f.Name())
}
出力は次のようになります。
2020/04/04 03:54:48 true
2020/04/04 03:54:48 17410619
2020/04/04 03:54:48 /Users/lurongming/main.go
2020/04/04 03:54:48 9
2020/04/04 03:54:48 main.main
2020/04/04 03:54:48 17411178
2020/04/04 03:54:48 /Users/lurongming/main.go
2020/04/04 03:54:48 34
2020/04/04 03:54:48 true
2020/04/04 03:54:48 main.test2
2020/04/04 03:54:48 17410624
2020/04/04 03:54:48 /Users/lurongming/main.go
2020/04/04 03:54:48 13
2020/04/04 03:54:48 true
2020/04/04 03:54:48 main.test
関数ポインタから直接ファイルを取得する機能の名前:
package main
import (
"log"
"reflect"
"runtime"
)
type Demo struct {
}
func (this *Demo) Hello() {
}
func main() {
demo := new(Demo)
pc := reflect.ValueOf(demo.Hello).Pointer()
f := runtime.FuncForPC(pc)
log.Println(f.Name())
log.Println(f.FileLine(pc))
}
出力は次のようになります。
2020/04/04 03:55:47 main.(*Demo).Hello-fm
2020/04/04 03:55:47 /Users/lurongming/main.go 12
FUNCコーラー(int型スキップ、PC [] uintptr)INT
uintptrに配置された呼び出しステーションにプログラムカウンタに戻り、発信者へ。
自体の発呼者0、および発信者が上記の歴史的な理由のために、同じではない、このパラメータの意味。わずか1 0上に、この対応します。
package main
import (
"fmt"
"runtime"
)
func printMyName() string {
pc, _, _, _ := runtime.Caller(1)
return runtime.FuncForPC(pc).Name()
}
func printCallerName() string {
pc, _, _, _ := runtime.Caller(2)
return runtime.FuncForPC(pc).Name()
}
func Foo() {
fmt.Printf("我是 %s, %s 在调用我!\n", printMyName(), printCallerName())
Bar()
}
func Bar() {
fmt.Printf("我是 %s, %s 又在调用我!\n", printMyName(), printCallerName())
trace()
}
func trace() {
pc := make([]uintptr, 10) // at least 1 entry needed
n := runtime.Callers(0, pc)
for i := 0; i < n; i++ {
f := runtime.FuncForPC(pc[i])
file, line := f.FileLine(pc[i])
fmt.Printf("%s:%d %s\n", file, line, f.Name())
}
}
func main() {
Foo()
}
出力は次のようになります。
我是 main.Foo, main.main 在调用我!
我是 main.Bar, main.Foo 又在调用我!
/usr/local/go/src/runtime/extern.go:211 runtime.Callers
/Users/lurongming/main.go:27 main.trace
/Users/lurongming/main.go:24 main.Bar
/Users/lurongming/main.go:20 main.Foo
/Users/lurongming/main.go:37 main.main
/usr/local/go/src/runtime/proc.go:212 runtime.main
/usr/local/go/src/runtime/asm_amd64.s:1358 runtime.goexit
CallersFrames(発信者[] uintptr)*フレーム
発信者は上記または単にプログラムカウンタをスタック、あなたはスタック全体についての情報を取得したい場合、あなたはトラバースコールFuncForPCする必要がなくなり、CallersFrames機能を使用することができます。
上記トレース機能は、以下のように変更することができ、出力結果は同じです。
func trace() {
pc := make([]uintptr, 10) // at least 1 entry needed
n := runtime.Callers(0, pc)
frames := runtime.CallersFrames(pc[:n])
for {
frame, more := frames.Next()
fmt.Printf("%s:%d %s\n", frame.File, frame.Line, frame.Function)
if !more {
break
}
}
}
スタック取得プログラム
あなたがプログラム内の情報を取得したい場合は、プログラムのパニックでは、一般的には、スタックのスタックを戦いを取るだろう、あなたはdebug.PrintStackは()プリントアウトすることができます。たとえば、あなたがプログラムのエラーを実行するのですが、プログラムのパニックを期待していない、単にデバッグ情報をスタックトレースをプリントアウトしたい、あなたはdebug.PrintStack()を使用することができます。
それとも、あなたはスタック情報、独自の処理や印刷をお読みください。
func DumpStacks() {
buf := make([]byte, 16384)
buf = buf[:runtime.Stack(buf, true)]
fmt.Printf("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf)
}
参考デバッグツールました。:stackTraceのダンプゴルーチン。
情報はまた、ゴルーチンIDのスタックを使用して得を参照することができる。その後、取得方法のゴルーチンのIDについて話します。
func GoID() int {
var buf [64]byte
n := runtime.Stack(buf[:], false)
idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0]
id, err := strconv.Atoi(idField)
if err != nil {
panic(fmt.Sprintf("cannot get goroutine id: %v", err))
}
return id
}