精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

如何在Go的函數中得到調用者函數名?

開發 前端
有時候在Go的函數調用的過程中,我們需要知道函數被誰調用,比如打印日志信息等。例如下面的函數,我們希望在日志中打印出調用者的名字。

有時候在Go的函數調用的過程中,我們需要知道函數被誰調用,比如打印日志信息等。例如下面的函數,我們希望在日志中打印出調用者的名字。

如何在Go的函數中得到調用者函數名?

 

  1. func Foo() { 
  2.     fmt.Println("誰在調用我?"
  3.     bar() 
  4. func Bar() { 
  5.     fmt.Println("誰又在調用我?"

首先打印函數本身的名稱

最簡單的方式就是硬編碼。 因為在編譯之前,我們肯定知道打印的時候所在哪個函數,但是更好的方式是編寫一個通用的函數,比如下面的例子:

 

  1. package main 
  2. import ( 
  3.     "fmt" 
  4.     "runtime" 
  5. func main() { 
  6.     Foo() 
  7. func Foo() { 
  8.     fmt.Printf("我是 %s, 誰在調用我?\n", printMyName()) 
  9.     Bar() 
  10. func Bar() { 
  11.     fmt.Printf("我是 %s, 誰又在調用我?\n", printMyName()) 
  12. func printMyName() string { 
  13.     pc, _, _, _ := runtime.Caller(1) 
  14.     return runtime.FuncForPC(pc).Name() 

輸出結果:

  1. 我是 main.Foo, 誰在調用我? 
  2. 我是 main.Bar, 誰又在調用我? 

可以看到函數在被調用的時候,printMyName把函數本身的名字打印出來了,注意這里Caller的參數是1, 因為我們將業務代碼封裝成了一個函數。

首先打印函數調用者的名稱

將上面的代碼修改一下,增加一個新的printCallerName的函數,可以打印調用者的名稱。

 

  1. func main() { 
  2.     Foo() 
  3. func Foo() { 
  4.     fmt.Printf("我是 %s, %s 在調用我!\n", printMyName(), printCallerName()) 
  5.     Bar() 
  6. func Bar() { 
  7.     fmt.Printf("我是 %s, %s 又在調用我!\n", printMyName(), printCallerName()) 
  8. func printMyName() string { 
  9.     pc, _, _, _ := runtime.Caller(1) 
  10.     return runtime.FuncForPC(pc).Name() 
  11. func printCallerName() string { 
  12.     pc, _, _, _ := runtime.Caller(2) 
  13.     return runtime.FuncForPC(pc).Name() 

相關函數介紹

你可以通過runtime.Caller、runtime.Callers、runtime.FuncForPC等函數更詳細的跟蹤函數的調用堆棧。

1、func Caller(skip int) (pc uintptr, file string, line int, ok bool)

Caller可以返回函數調用棧的某一層的程序計數器、文件信息、行號。

0 代表當前函數,也是調用runtime.Caller的函數。1 代表上一層調用者,以此類推。

2、func Callers(skip int, pc []uintptr) int

Callers用來返回調用站的程序計數器, 放到一個uintptr中。

0 代表 Callers 本身,這和上面的Caller的參數的意義不一樣,歷史原因造成的。 1 才對應這上面的 0。

比如在上面的例子中增加一個trace函數,被函數Bar調用。

 

  1. …… 
  2. func Bar() { 
  3.     fmt.Printf("我是 %s, %s 又在調用我!\n", printMyName(), printCallerName()) 
  4.     trace() 
  5. func trace() { 
  6.     pc := make([]uintptr, 10) // at least 1 entry needed 
  7.     n := runtime.Callers(0, pc) 
  8.     for i := 0; i < n; i++ { 
  9.         f := runtime.FuncForPC(pc[i]) 
  10.         file, line := f.FileLine(pc[i]) 
  11.         fmt.Printf("%s:%d %s\n", file, line, f.Name()) 
  12.     } 

輸出結果可以看到這個goroutine的整個棧都打印出來了:

 

  1. /usr/local/go/src/runtime/extern.go:218 runtime.Callers 
  2. /Users/yuepan/go/src/git.intra.weibo.com/platform/tool/g/main.go:34 main.trace 
  3. /Users/yuepan/go/src/git.intra.weibo.com/platform/tool/g/main.go:20 main.Bar 
  4. /Users/yuepan/go/src/git.intra.weibo.com/platform/tool/g/main.go:15 main.Foo 
  5. /Users/yuepan/go/src/git.intra.weibo.com/platform/tool/g/main.go:10 main.main 
  6. /usr/local/go/src/runtime/proc.go:210 runtime.main 
  7. /usr/local/go/src/runtime/asm_amd64.s:1334 runtime.goexit 

3、func CallersFrames(callers []uintptr) *Frames

上面的Callers只是或者棧的程序計數器,如果想獲得整個棧的信息,可以使用CallersFrames函數,省去遍歷調用FuncForPC。

上面的trace函數可以更改為下面的方式:

 

  1. func trace2() { 
  2.     pc := make([]uintptr, 10) // at least 1 entry needed 
  3.     n := runtime.Callers(0, pc) 
  4.     frames := runtime.CallersFrames(pc[:n]) 
  5.     for { 
  6.         frame, more := frames.Next() 
  7.         fmt.Printf("%s:%d %s\n", frame.File, frame.Line, frame.Function
  8.         if !more { 
  9.             break 
  10.         } 
  11.     } 

4、func FuncForPC(pc uintptr) *Func

FuncForPC 是一個有趣的函數, 它可以把程序計數器地址對應的函數的信息獲取出來。如果因為內聯程序計數器對應多個函數,它返回最外面的函數。

它的返回值是一個*Func類型的值,通過*Func可以獲得函數地址、文件行、函數名等信息。

除了上面獲取程序計數器的方式,也可以通過反射的方式獲取函數的地址:

  1. runtime.FuncForPC(reflect.ValueOf(foo).Pointer()).Name() 

5、獲取程序堆棧

在程序panic的時候,一般會自動把堆棧打出來,如果你想在程序中獲取堆棧信息,可以通過debug.PrintStack()打印出來。比如你在程序中遇到一個Error,但是不期望程序panic,只是想把堆棧信息打印出來以便跟蹤調試,你可以使用debug.PrintStack()。

抑或,你自己讀取堆棧信息,自己處理和打印:

 

  1. func DumpStacks() { 
  2.     buf := make([]byte, 16384) 
  3.     buf = buf[:runtime.Stack(buf, true)] 
  4.     fmt.Printf("=== BEGIN goroutine stack dump ===\n%s\n=== END goroutine stack dump ===", buf) 

參考 調試利器:dump goroutine 的 stacktrace。

利用堆棧信息還可以獲取goroutine的id, 參考: 再談談獲取 goroutine id 的方法

 

  1. func GoID() int { 
  2.     var buf [64]byte 
  3.     n := runtime.Stack(buf[:], false
  4.     idField := strings.Fields(strings.TrimPrefix(string(buf[:n]), "goroutine "))[0] 
  5.     id, err := strconv.Atoi(idField) 
  6.     if err != nil { 
  7.         panic(fmt.Sprintf("cannot get goroutine id: %v", err)) 
  8.     } 
  9.     return id 

 

責任編輯:未麗燕 來源: 鳥窩
相關推薦

2022-05-05 09:02:24

Go函數調用棧

2020-06-17 17:29:11

BashLinux

2021-09-15 07:56:33

函數類型Go

2021-11-28 06:47:32

Python函數開發

2021-11-02 12:19:18

Go函數結構

2021-07-09 12:37:31

GoPython編程語言

2010-01-28 13:35:41

調用C++函數

2010-07-28 15:29:18

Flex函數

2017-07-27 15:52:10

函數調用堆棧結構

2009-07-10 17:54:15

Java中調用JythJython

2023-10-23 19:27:21

Go函數

2018-08-27 14:50:46

LinuxShellBash

2019-12-02 21:29:45

Keras神經網絡TensorFlow

2010-09-10 16:02:13

SQLCHARINDEX函數

2023-11-26 19:06:13

GO測試

2021-12-27 08:53:23

Go函數 Nil

2022-01-14 15:05:56

函數調用代碼Linux

2009-06-17 13:19:50

Java調用DLL

2022-09-19 11:42:21

Go優化CPU

2020-05-06 20:40:03

Go編程語言
點贊
收藏

51CTO技術棧公眾號

五月婷婷之婷婷| 狠狠色噜噜狠狠狠狠色吗综合| 国产不卡在线观看视频| 91精品国产自产观看在线 | 98国产高清一区| 日韩xxx高潮hd| 日韩欧美二区| 亚洲电影在线看| 777一区二区| 午夜久久中文| 亚洲欧美激情一区二区| 玖玖玖精品中文字幕| 亚洲资源在线播放| 99精品视频网| 免费91在线视频| 久久成人激情视频| 豆花视频一区二区| 欧美日韩中文字幕一区二区| 18黄暴禁片在线观看| 国产毛片av在线| av在线播放成人| 亚洲一区二区免费| 中文字幕在线观看视频免费| 亚洲一级一区| 久久久成人的性感天堂| 国产精品天天干| 成人资源在线| 欧美一区二区三区免费观看视频| 国产精品99久久免费黑人人妻| av在线麻豆| 国产精品美女久久久久久久久久久| 久久国产精品-国产精品| 国产99999| 看国产成人h片视频| 日韩美女免费观看| 日韩欧美性视频| 欧美国产91| 久久精品国产一区二区电影| 欧美人与性囗牲恔配| 日本国产精品| 亚洲国产天堂久久综合网| 国产精品二区视频| 日韩高清二区| 日韩欧美中文字幕一区| 999热精品视频| 4438五月综合| 欧美高清视频在线高清观看mv色露露十八| 成年人在线看片| 在线天堂新版最新版在线8| 亚洲国产精品久久一线不卡| 久久福利一区二区| 午夜影院免费在线| 亚洲一区二区三区小说| av 日韩 人妻 黑人 综合 无码| 色影视在线观看| 国产精品美女www爽爽爽| 天堂√在线观看一区二区| 高清福利在线观看| 亚洲国产精品ⅴa在线观看| 亚洲成人午夜在线| 日本中文字幕在线2020| 亚洲欧美在线另类| 日产精品久久久久久久蜜臀| av小说在线播放| 精品高清美女精品国产区| 国产视频九色蝌蚪| 中文字幕在线视频久| 一本一道久久a久久精品| 激情婷婷综合网| 国产成人午夜性a一级毛片| 欧美裸体bbwbbwbbw| 日本精品一区在线| av成人资源网| 精品视频一区在线视频| 黄色片网站免费| 91精品国产麻豆国产在线观看| 萌白酱国产一区二区| 国产乱码久久久久久| 亚洲综合不卡| 国产噜噜噜噜噜久久久久久久久 | 国产精品高清乱码在线观看| 欧美日韩综合在线| 久久久久亚洲av无码麻豆| 97超碰成人| 亚洲美女福利视频网站| 日韩精品久久久久久久的张开腿让| 91精品国产视频| 91精品国产网站| 羞羞色院91蜜桃| 国产精品一级片在线观看| 国产亚洲一区在线播放| 粉嫩av一区| 一卡二卡三卡日韩欧美| 久久国产乱子伦免费精品| 国产精品麻豆成人av电影艾秋| 51精品久久久久久久蜜臀| 色婷婷精品久久二区二区密| 人人狠狠综合久久亚洲婷婷| 久久久久久久久久久网站| 中文字幕精品无| 岛国精品在线观看| 亚洲精品电影在线一区| 91吃瓜在线观看| 欧美日产国产精品| 中文在线永久免费观看| 欧美激情国产在线| 国产91ⅴ在线精品免费观看| 国产精品亚洲lv粉色| 91麻豆高清视频| 中国一级黄色录像| 日韩大尺度黄色| 精品日韩一区二区| 婷婷丁香综合网| 午夜亚洲一区| 国产91一区二区三区| 一级毛片视频在线| 一本久道久久综合中文字幕| av在线网站免费观看| 激情综合网站| 久久免费少妇高潮久久精品99| 伊人网中文字幕| 91天堂素人约啪| 国产乱淫av片杨贵妃| 四虎国产精品免费久久5151| 亚洲美女av黄| 国产精品久久久久久99| 国产成人av自拍| www.-级毛片线天内射视视| 深夜视频一区二区| 亚洲毛片在线观看.| 日韩久久精品视频| 岛国一区二区在线观看| 国产一区二区三区在线免费| av日韩久久| 日韩视频在线免费观看| 成人黄色三级视频| 国产日韩欧美激情| 激情五月亚洲色图| 国产成人精品免费视| 91成人性视频| 视频一区二区在线播放| 婷婷六月综合亚洲| 在线精品一区二区三区| 亚洲精选久久| 久久综合一区二区三区| www在线观看黄色| 亚洲国产精彩中文乱码av在线播放 | 久久精品99国产| 亚洲aaa级| 欧美一级淫片播放口| 日本护士...精品国| 欧美性xxxx极品hd欧美风情| 国产精品一级黄片| 模特精品在线| 日韩jizzz| 丰满少妇一区| 日韩亚洲欧美成人| 国产麻豆一精品一男同| 亚洲美女免费在线| 91porn在线| 亚洲视频www| 日韩欧美第二区在线观看| 国产经典一区| www.亚洲成人| 亚洲av无码乱码国产精品| 午夜久久久影院| wwwwxxxx国产| 美女国产一区二区| 国产树林野战在线播放| 凹凸av导航大全精品| 欧美在线视频a| 国产黄色片在线播放| 欧美年轻男男videosbes| 亚洲天堂黄色片| av男人天堂一区| 国产成人av影视| 久久久久av| 国产欧美一区二区三区另类精品 | 国产性生活毛片| 久久精品亚洲一区二区| 亚洲一区三区视频在线观看| 少妇精品在线| 日产日韩在线亚洲欧美| 免费看美女视频在线网站| 欧美xxxx在线观看| 无码人妻aⅴ一区二区三区有奶水| 亚洲图片欧美激情| 成人在线电影网站| 美国一区二区三区在线播放| 久久福利一区二区| 欧美日韩有码| 国产精品一区二区三区免费| www.国产精品| 久久久久久一区二区三区| 国产中文字幕在线| 欧美成人伊人久久综合网| 无码人妻精品一区二区50| 亚洲美女免费在线| 手机毛片在线观看| 成人av免费观看| 艹b视频在线观看| 亚洲三级视频| 欧洲美女和动交zoz0z| 国产精品一区二区99| av观看久久| 99久久伊人| 91精品国产乱码久久久久久久久 | 欧美在线欧美在线| 亚洲第一图区| 自拍亚洲一区欧美另类| 日本韩国在线观看| 欧美精品欧美精品系列| 久久久久久在线观看| 亚洲成人手机在线| 久久精品一区二区三区四区五区 | 欧美性xxxx69| 超碰成人97| 91久久中文字幕| 91另类视频| 欧洲亚洲免费在线| segui88久久综合9999| 美女精品视频一区| 欧美jizzhd69巨大| 永久免费精品影视网站| 亚洲日本中文字幕在线| 精品国产免费视频| 国产高清视频免费观看| 69精品人人人人| 中日韩av在线| 91极品视觉盛宴| 欧美性猛交bbbbb精品| 午夜久久福利影院| 国产精品不卡av| 亚洲国产成人av网| 国产精品第九页| 亚洲国产你懂的| 久久亚洲国产成人精品性色| 一区二区三区高清在线| 午夜国产福利一区二区| 亚洲欧洲日韩在线| 国产日产精品一区二区三区的介绍| 国产精品免费aⅴ片在线观看| 少妇愉情理伦三级| 国产精品女人毛片| 国产传媒视频在线| 亚洲欧美自拍偷拍色图| 91视频综合网| 一区二区三区日韩在线观看| 久久免费在线观看视频| 亚洲va欧美va天堂v国产综合| 九热这里只有精品| 午夜亚洲国产au精品一区二区| 亚洲国产精品午夜在线观看| 都市激情亚洲色图| 国产亚洲欧美在线精品| 在线观看亚洲一区| 亚洲影院一区二区三区| 91精品在线观看入口| a天堂在线观看视频| 欧美成人国产一区二区| 天天干,夜夜爽| 亚洲女人初尝黑人巨大| 成年在线电影| 久久精品国产亚洲一区二区| 青草av在线| 538国产精品一区二区免费视频| 黑人巨大精品| 91精品久久久久| 一区二区三区免费在线看| 精品欧美一区二区精品久久| 美女网站一区| 欧美一级免费在线观看| 狠久久av成人天堂| 好男人www社区| 国产乱码一区二区三区| 青青草视频播放| 日本一区二区三区高清不卡| 成人在线观看小视频| 精品福利视频导航| 在线观看日韩一区二区| 日韩美女主播在线视频一区二区三区| 亚洲三区在线观看无套内射| 一本久久综合亚洲鲁鲁| a在线免费观看| 91黄色8090| 91久久青草| 欧美精品七区| 久久久国产精品| 久章草在线视频| 国产精品性做久久久久久| 久久精品一区二区免费播放| 国产精品久久久久久久久久免费看| 久热这里只有精品在线| 色狠狠桃花综合| 懂色av蜜臀av粉嫩av分享吧| 国产一区二区三区丝袜| 国产精品186在线观看在线播放| 国产国产精品人在线视| 亚洲一区二区三区中文字幕在线观看| 欧美日韩一区在线观看视频| 国产一区清纯| 亚洲成人福利在线| 91在线云播放| 青青操视频在线播放| 欧美性猛交一区二区三区精品| 蜜臀av午夜精品| 精品久久久av| 欧美aaa视频| 久久精品日产第一区二区三区| 无需播放器亚洲| 精品999在线| 久久综合一区二区| 日本五十熟hd丰满| 日韩一二三区视频| 日本中文字幕伦在线观看| 欧美亚洲成人xxx| a级日韩大片| av磁力番号网| 久久99精品国产麻豆婷婷洗澡| 少妇真人直播免费视频| 亚洲国产你懂的| 亚洲av无码乱码国产精品| 久久综合九色九九| 欧美午夜三级| 亚洲国产精品www| 日韩va欧美va亚洲va久久| 人人妻人人澡人人爽人人精品| 亚洲成在人线免费| 成人久久精品人妻一区二区三区| 欧美成人午夜激情| 国产精品2区| 欧美 日韩 国产 在线观看| 久久精品国产99久久6| 青娱乐国产视频| 日本精品视频一区二区| 黄色片在线免费观看| 欧洲日本亚洲国产区| 网红女主播少妇精品视频| 激情五月宗合网| www国产精品av| 超碰超碰超碰超碰| 国产偷国产偷亚洲清高网站| 电影在线观看一区| 久久久久高清| 亚洲一区二区三区高清不卡| 色呦呦一区二区| 欧美性猛交xxxx偷拍洗澡| 你懂的免费在线观看视频网站| 国产99在线|中文| 狠狠做六月爱婷婷综合aⅴ| 黑人粗进入欧美aaaaa| 国产精品日产欧美久久久久| 亚洲午夜无码久久久久| 色小说视频一区| 91精品福利观看| 成人在线播放网址| 91在线高清观看| 亚洲精品一区二区二区| 日韩在线观看免费网站| 欧洲大片精品免费永久看nba| 特级西西人体www高清大胆| 成人综合在线观看| 日本中文在线播放| 亚洲图片欧洲图片av| 日韩久久一区| 隔壁人妻偷人bd中字| 91视频一区二区三区| 最新国产中文字幕| 久久中文字幕在线| 久久久久久毛片免费看 | 黄色国产一级视频| 国产午夜精品一区二区三区嫩草 | 国产成人精品免费看在线播放 | 欧美videos另类精品| 国产在线一区二区三区播放| 久久激情网站| 91插插插插插插| 亚洲精品久久久久中文字幕二区| 免费成人直播| 欧美h视频在线观看| 91免费观看国产| 国产乱淫av免费| 91av在线看| **女人18毛片一区二区| 国产真实乱人偷精品| 精品视频1区2区| 国产盗摄精品一区二区酒店| 日本一区二区久久精品| 国产美女精品人人做人人爽| 亚洲天堂视频网站| 久久资源免费视频| 国产一区二区亚洲| 国产精品熟妇一区二区三区四区 | 精品人妻一区二区三区四区不卡 | 又大又硬又爽免费视频| 国产精品入口麻豆九色| 午夜福利视频一区二区| 91精品视频在线| 手机精品视频在线观看| 国产在线一二区|