返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

Stack

发布于 2024-10-12 19:15:54 字数 1709 浏览 0 评论 0 收藏 0

获取调用堆栈(call stack)信息。

func main() {
    done := make(chan struct{})
    
    go func() {
        defer close(done)
        
        buf := make([]byte, 2<<10)
        n := runtime.Stack(buf, true)  // false: 仅当前 G。
        println(string(buf[:n]))
    }()
    
    <- done
}

/*

goroutine 17 [running]:
main.main.func1()
	test/main.go:22 +0x7e
created by main.main
	test/main.go:18 +0x6a

goroutine 1 [chan receive]:
main.main()
	test/main.go:26 +0x76
    
*/

利用 CallerCallers 获取栈帧(stack frame)信息。

参数 skip 表示向外跳过的栈帧数。

0 : 调用 Caller 的函数( test )。
1 : 是 main 函数。

返回 pc 表示 PC/IP 值。

package main

import (
	"fmt"
	"log"
	"runtime"
)

//go:noinline
func test() {
	pc, file, line, ok := runtime.Caller(0)
	if !ok { log.Fatal() }

	fn := runtime.FuncForPC(pc)
	fmt.Printf("name: %s\nfile: %s:%d\n", fn.Name(), file, line)
}

func main() {
	test()
}

/*

name: main.test
file: test/main.go:11

*/

注意, Caller(0) 表示其调用者( test ),而 Callers(0) 第一帧代表其自身。

package main

import (
	"runtime"
)

//go:noinline
func test() {
	buf := make([]uintptr, 100)
	n := runtime.Callers(0, buf)
	frames := runtime.CallersFrames(buf[:n])

	for {
		f, more := frames.Next()
		println(f.Function, f.File, f.Line)

		if !more { break }
	}
}

func main() {
	test()
}

/*

runtime.Callers runtime/extern.go 235
main.test       test/main.go 10
main.main       test/main.go 22
runtime.main    runtime/proc.go 250
runtime.goexit  runtime/asm_amd64.s 1571

*/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文