精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

又粗又黑又大的吊av| 成人乱人伦精品视频在线观看| youjizz.com日本| 国产传媒在线观看| 国产欧美一区二区在线观看| 成人国产精品久久久| 久久久久久久久久91| 蜜桃a∨噜噜一区二区三区| 欧美日韩情趣电影| 欧洲精品一区二区三区久久| 国产在线资源| 国产寡妇亲子伦一区二区| 97超级碰碰碰| 精品国产视频在线观看| 欧美大片网址| 555夜色666亚洲国产免| 欧美 日韩 国产一区| 国产精品扒开做爽爽爽的视频| av不卡一区二区三区| 国产欧美在线看| 国产三级精品三级在线观看| 午夜久久福利| 最近2019年手机中文字幕| 久久久久久久人妻无码中文字幕爆| 中文.日本.精品| 亚洲一区二区精品3399| 永久久久久久| 黄色电影免费在线看| 丰满岳乱妇一区二区三区| 国产精品福利在线| 51国产偷自视频区视频| 亚洲国产成人精品女人| 伊人成人开心激情综合网| 第四色在线视频| 日韩成人视屏| 欧美精品三级日韩久久| 日韩av片网站| 在线免费日韩片| 黄网动漫久久久| 国产91沈先生在线播放| 免费黄色在线看| 久久精品水蜜桃av综合天堂| 精品欧美一区二区在线观看视频| 99热这里只有精品9| 捆绑调教美女网站视频一区| 国产精品9999| 69亚洲精品久久久蜜桃小说| 一区二区精品| 91爱爱小视频k| 国产网友自拍视频| 欧美日本不卡| 欧美精品在线免费观看| 在线观看黄网址| 91久久夜色精品国产按摩| 中文字幕欧美精品在线| 美国一级黄色录像| 色喇叭免费久久综合| 中文字幕av一区| av免费播放网站| 成人精品电影| 日日骚久久av| 少妇高潮在线观看| 91精品天堂福利在线观看| 日韩视频在线一区| 波多野结衣亚洲一区二区| 亚洲精品小说| 欧美国产中文字幕| 久久精品久久国产| 亚洲狼人精品一区二区三区| 7m第一福利500精品视频| 午夜精品久久久久久久久久久久久蜜桃| 伊人久久成人| 欧美专区中文字幕| 少妇久久久久久久| 蜜臀va亚洲va欧美va天堂| 国产免费一区视频观看免费| 99精品免费观看| 国产98色在线|日韩| 精品国产免费一区二区三区 | 国产又粗又猛又爽又黄av| 国产精品入口久久| 色偷偷91综合久久噜噜| 国产黄色片在线| 欧美日韩1区| 欧美亚洲激情视频| 一区二区三区麻豆| 国产在线播放一区三区四| 999热视频在线观看| 欧美一级免费片| 国产欧美精品一区二区色综合朱莉| 亚洲欧美在线网| 人妖欧美1区| 在线一区二区三区做爰视频网站| 亚洲欧美日韩三级| 激情av综合| 亚洲欧洲免费视频| 极品颜值美女露脸啪啪| 在线视频亚洲| 成人欧美一区二区三区在线湿哒哒| 亚洲乱码国产乱码精品精软件| 久久亚洲一区二区三区明星换脸 | 搡老熟女老女人一区二区| 国产亚洲一卡2卡3卡4卡新区| 久久久av电影| 亚洲va在线观看| 国产在线日韩欧美| 麻豆av一区二区| 成人影欧美片| 色狠狠av一区二区三区| 日本r级电影在线观看| 亚洲精品亚洲人成在线观看| 久久伊人色综合| 9i精品福利一区二区三区| 国产精品白丝jk黑袜喷水| 欧美日韩日本网| 羞羞的视频在线观看| 欧美综合一区二区三区| 国产白袜脚足j棉袜在线观看| 成人在线免费观看视频| 97在线观看免费高清| 91免费视频播放| 国产喷白浆一区二区三区| 成人午夜视频免费观看| 欧美少妇激情| 亚洲欧美中文另类| 国产精彩视频在线| 国产乱子伦一区二区三区国色天香| 欧美日本韩国在线| 高清在线视频不卡| 欧美大胆一级视频| 午夜精品一区二区三级视频| 久久久亚洲一区| 国内不卡一区二区三区| 日韩少妇视频| 日韩午夜激情av| 久久人妻无码aⅴ毛片a片app| 久久影院亚洲| 欧美成ee人免费视频| caoprom在线| 日韩午夜精品视频| 国产探花在线播放| 国内精品国产成人| 一区二区在线高清视频| 欧美成人家庭影院| 中文字幕欧美日韩va免费视频| 国产区一区二区三| 99久久伊人精品| 国产69精品久久久久999小说| 日韩精品三级| 欧美国产在线视频| 韩国av电影在线观看| 一区二区三区国产精品| 波多野结衣电影免费观看| 一级毛片免费高清中文字幕久久网| 成人网址在线观看| av免费在线观| 日韩三级.com| 久久视频免费在线观看| 97久久精品人人澡人人爽| 波多野结衣之无限发射| 日韩母乳在线| 国产91色在线|| 风间由美一区| 欧美日韩极品在线观看一区| www.xx日本| 国产乱码精品一区二区三区忘忧草 | 一级久久久久久久| 亚洲色图视频网| 色婷婷狠狠18禁久久| 影音先锋亚洲一区| 麻豆精品传媒视频| 亚洲a∨精品一区二区三区导航| 永久免费看mv网站入口亚洲| 亚洲天堂狠狠干| 亚洲精品成a人| 成年人的黄色片| 日韩高清国产一区在线| 日本特级黄色大片| 国产精品2023| 国产精品久久久久99| 视频三区在线| 欧美精品一区二区在线观看| 天天干天天干天天| 亚洲天堂久久久久久久| 在线xxxxx| 日本sm残虐另类| 99久久99久久精品| 香蕉视频一区| 成人亚洲欧美一区二区三区| 182在线视频观看| 正在播放国产一区| 亚洲成人中文字幕在线| 日韩欧美中文在线| www.av成人| 99re这里都是精品| 五月婷婷丁香色| 亚洲青色在线| 国产精品99久久久久久大便| 乱亲女h秽乱长久久久| 国产精品网红福利| 182在线视频观看| 日韩中文在线观看| 天天操天天操天天| 欧美乱妇20p| 免费观看一区二区三区毛片| 中文字幕佐山爱一区二区免费| 亚洲精品乱码久久久久久蜜桃欧美| 日韩精彩视频在线观看| 国产a级黄色大片| 清纯唯美亚洲综合一区| 激情小说网站亚洲综合网| 99综合99| 国产精品成人aaaaa网站| 久久av色综合| 精品国产一区二区三区在线观看| 三级av在线| 亚洲精品在线免费播放| 国产精品主播一区二区| 日本韩国欧美一区二区三区| 亚洲国产精品午夜在线观看| 亚洲欧洲av一区二区三区久久| 人妻丰满熟妇av无码久久洗澡| 国产精品18久久久久久久久| 久久久久久久久久久久91| 中文欧美日韩| 国产亚洲黄色片| 欧美福利专区| 中文字幕久久一区| 欧美午夜精彩| 欧美日韩一区二区三| 青青草久久爱| 国产日韩欧美亚洲一区| 美女久久精品| 成人美女免费网站视频| 成人精品一区二区三区电影| 日产日韩在线亚洲欧美 | 国产成人一区二区在线| av手机在线观看| 欧美精品久久久久久久久| 中文字幕免费高清电视剧网站在线观看| www.欧美三级电影.com| av中文资源在线| 中文字幕av一区| av大片在线观看| 色综合影院在线| 欧美一级二级三级区| 久久久国产影院| 91中文在线| 欧美大片在线影院| 国产精品—色呦呦| 国内揄拍国内精品| 蜜桃av在线播放| 2019日本中文字幕| 97成人资源| 国产国产精品人在线视| 电影亚洲一区| 91老司机精品视频| 日韩三级久久| 国产精品国产精品国产专区不卡| 一区二区三区高清在线观看| 国产精品中出一区二区三区| 全国精品免费看| 日产精品久久久一区二区| 日韩成人综合| 热这里只有精品| 尤物在线精品| 干日本少妇首页| 麻豆国产精品一区二区三区| 中文字幕亚洲乱码| 国产精品一区二区免费不卡| 午夜不卡久久精品无码免费| 久久综合久久综合久久| 秋霞网一区二区三区| 亚洲日本一区二区三区| 欧美激情一区二区视频| 午夜精品久久久久久久久久| 久久久精品视频网站| 欧美美女bb生活片| 亚洲成人第一区| 亚洲偷欧美偷国内偷| 日本在线观看| 国内揄拍国内精品少妇国语| 成人开心激情| 亚洲在线观看视频| 欧洲精品一区| 一区二区三区四区欧美日韩| 一区精品久久| 日韩av在线中文| 波波电影院一区二区三区| 亚洲精品视频网址| 一区二区三区欧美视频| 久久夜色精品国产噜噜亚洲av| 欧美日韩国产免费| 日批视频免费播放| 日韩在线观看免费| 九九精品调教| 国产精品久久久久久久久粉嫩av| 久久gogo国模啪啪裸体| 久久久久久久有限公司| 我不卡影院28| 女人扒开屁股爽桶30分钟| 狠狠色伊人亚洲综合成人| 亚洲国产欧美视频| 亚洲男帅同性gay1069| 免费av网站在线| 日韩美女主播在线视频一区二区三区| 你懂的免费在线观看视频网站| www.美女亚洲精品| 高清成人在线| 国产日韩欧美一区二区| 综合五月婷婷| 麻豆一区二区三区视频| 91在线观看高清| 久久久99精品| 91精品国产综合久久精品图片| 六十路在线观看| 午夜精品福利在线观看| 免费一级欧美在线大片| 午夜精品一区二区三区四区| 一本久久综合| 师生出轨h灌满了1v1| 国产精品久久二区二区| 一二三区免费视频| 日韩国产欧美区| 美洲精品一卡2卡三卡4卡四卡| 成人福利视频网| 精品毛片免费观看| 2022亚洲天堂| 91在线精品秘密一区二区| 美女视频黄免费| 91精品国产免费久久综合| 在线播放日本| 国产欧美一区二区白浆黑人| 欧美日韩性在线观看| 日韩av播放器| 久久理论电影网| 国产精品777777| 亚洲精品xxxx| 亚洲优女在线| 免费一区二区三区| 国产精品嫩草99av在线| 波多野结衣视频播放| 亚洲国产cao| 人人妻人人澡人人爽人人欧美一区 | 亚洲AV无码成人精品区明星换面| 精品久久久一区二区| 人妻无码一区二区三区久久99| 久久久亚洲精品视频| 66精品视频在线观看| 国内自拍中文字幕| 福利电影一区二区| 日韩 欧美 亚洲| 亚洲精品mp4| 久久电影tv| 四虎永久国产精品| 青青草国产成人av片免费| 国产又粗又黄又猛| 欧美日韩一区三区四区| 99青草视频在线播放视| 成人黄色av播放免费| 亚洲九九在线| 波多野结衣办公室双飞| 激情成人中文字幕| 黄色在线视频观看网站| 国产精品美女呻吟| 久久久久久久久丰满| 国产伦理在线观看| 亚洲福利视频一区| 无码国产精品96久久久久| 日本乱人伦a精品| 欧美在线免费看视频| 在线观看免费视频污| 亚洲综合免费观看高清完整版| 天堂在线视频观看| 国产成人综合一区二区三区| 欧美大人香蕉在线| 美女日批在线观看| 欧美性xxxxx极品娇小| 午夜免费福利在线观看| 国产91精品一区二区绿帽| 欧美一级播放| 污软件在线观看| 亚洲精品国产综合久久| 国产成+人+综合+亚洲欧美| 91嫩草国产丨精品入口麻豆| 91视频国产观看| 国产精品九九九九| 91精品国产免费久久久久久| 日韩系列欧美系列| 国产69视频在线观看| 欧美午夜宅男影院| 丝袜在线观看| 日本高清视频一区二区三区| 激情图片小说一区| 五月天婷婷久久| 久久综合九色九九| 国产aⅴ精品一区二区三区久久| 午夜不卡福利视频| 色哟哟一区二区在线观看 | 亚洲免费伊人电影|