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

C++的全鏈路追蹤方案,稍微有點高端

開發 后端
本文的知識點還是值得了解一下的,大家或許會用得到。在研究的過程中我也發現了一個基于此種方案的開源項目(call-stack-logger),感興趣的也可以去了解了解。

背景:本人主要在做C++ SDK的開發,需要給到業務端去集成,在集成的過程中可能會出現某些功能性bug,即沒有得到想要的結果。那怎么調試?

分析:這種問題其實調試起來稍微有點困難,它不像crash,當發生crash時還能拿到堆棧信息去分析,然而功能性bug沒有crash,也就沒法捕捉對應到當時的堆棧信息。因為不是在本地,也沒法用編譯器debug。那思路就剩log了,一種方式是考慮在SDK內部的關鍵路徑下打印詳細的log,當出現問題時拿到log去分析。然而總有漏的時候,誰能保證log一定打的很全面,很有可能問題就出現在沒有log的函數中。

解決:基于上面的背景和問題分析,考慮是否能做一個全鏈路追蹤的方案,把打印出整個SDK的調用路徑,從哪個函數進入,從哪個函數退出等。

想法1:可以考慮在SDK的每個接口都加一個context結構體參數,記錄下來函數的調用路徑,這可能是比較通用有效的方案,但是SDK接口已經固定了,更改接口要面臨的困難很大,業務端基本不會同意,所以這種方案不適合我們現有情況,當然一個從0開始建設的中間件和SDK可以考慮考慮。

想法2:有沒有一種不用改接口,還能追蹤到函數調用路徑的方案?

繼續沿著這個思路繼續調研,我找到了gcc和clang編譯器的一個編譯參數:-finstrument-functions,編譯時添加此參數會在函數的入口和出口處觸發一個固定的回調函數,即:

  1. __cyg_profile_func_enter(void *callee, void *caller); 
  2. __cyg_profile_func_exit(void *callee, void *caller); 

參數就是callee和caller的地址,那怎么將地址解析成對應函數名?可以使用dladdr函數:

  1. int dladdr(const void *addr, Dl_info *info); 

看下下面的代碼:

  1. // tracing.cc 
  2.  
  3. #include <cxxabi.h> 
  4. #include <dlfcn.h>  // for dladdr 
  5. #include <stdio.h> 
  6. #include <stdlib.h> 
  7. #include <string.h> 
  8.  
  9. #ifndef NO_INSTRUMENT 
  10. #define NO_INSTRUMENT __attribute__((no_instrument_function)) 
  11. #endif 
  12.  
  13. extern "C" __attribute__((no_instrument_function)) void __cyg_profile_func_enter(void *callee, void *caller) { 
  14.     Dl_info info; 
  15.     if (dladdr(callee, &info)) { 
  16.         int status; 
  17.         const char *name
  18.         char *demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); 
  19.         if (status == 0) { 
  20.             name = demangled ? demangled : "[not demangled]"
  21.         } else { 
  22.             name = info.dli_sname ? info.dli_sname : "[no dli_sname nd std]"
  23.         } 
  24.  
  25.         printf("enter %s (%s)\n"name, info.dli_fname); 
  26.  
  27.         if (demangled) { 
  28.             free(demangled); 
  29.             demangled = NULL
  30.         } 
  31.     } 
  32.  
  33. extern "C" __attribute__((no_instrument_function)) void __cyg_profile_func_exit(void *callee, void *caller) { 
  34.     Dl_info info; 
  35.     if (dladdr(callee, &info)) { 
  36.         int status; 
  37.         const char *name
  38.         char *demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status); 
  39.         if (status == 0) { 
  40.             name = demangled ? demangled : "[not demangled]"
  41.         } else { 
  42.             name = info.dli_sname ? info.dli_sname : "[no dli_sname and std]"
  43.         } 
  44.         printf("exit %s (%s)\n"name, info.dli_fname); 
  45.  
  46.         if (demangled) { 
  47.             free((void *)demangled); 
  48.             demangled = NULL
  49.         } 
  50.     } 

這是測試文件:

  1. // test_trace.cc 
  2. void func1() {} 
  3.  
  4. void func() { func1(); } 
  5.  
  6. int main() { func(); } 
  7. 將test_trace.cc和tracing.cc文件同時編譯鏈接,即可達到鏈路追蹤的目的: 
  8. g++ test_trace.cc tracing.cc -std=c++14 -finstrument-functions -rdynamic -ldl;./a.out 
  9. 輸出:enter main (./a.out
  10. enter func() (./a.out
  11. enter func1() (./a.out
  12. exit func1() (./a.out
  13. exit func() (./a.out
  14. exit main (./a.out

如果在func()中調用了一些其他的函數呢?

  1. #include <iostream> 
  2. #include <vector> 
  3.  
  4. void func1() {} 
  5.  
  6. void func() { 
  7.     std::vector<int> v{1, 2, 3}; 
  8.     std::cout << v.size(); 
  9.     func1(); 
  10.  
  11. int main() { func(); } 

再重新編譯后輸出會是這樣:

  1. enter [no dli_sname nd std] (./a.out
  2. enter [no dli_sname nd std] (./a.out
  3. exit [no dli_sname and std] (./a.out
  4. exit [no dli_sname and std] (./a.out
  5. enter main (./a.out
  6. enter func() (./a.out
  7. enter std::allocator<int>::allocator() (./a.out
  8. enter __gnu_cxx::new_allocator<int>::new_allocator() (./a.out
  9. exit __gnu_cxx::new_allocator<int>::new_allocator() (./a.out
  10. exit std::allocator<int>::allocator() (./a.out
  11. enter std::vector<int, std::allocator<int> >::vector(std::initializer_list<int>, std::allocator<int> const&) (./a.out
  12. enter std::_Vector_base<int, std::allocator<int> >::_Vector_base(std::allocator<int> const&) (./a.out
  13. enter std::_Vector_base<int, std::allocator<int> >::_Vector_impl::_Vector_impl(std::allocator<int> const&) (./a.out
  14. enter std::allocator<int>::allocator(std::allocator<int> const&) (./a.out
  15. enter __gnu_cxx::new_allocator<int>::new_allocator(__gnu_cxx::new_allocator<int> const&) (./a.out
  16. exit __gnu_cxx::new_allocator<int>::new_allocator(__gnu_cxx::new_allocator<int> const&) (./a.out
  17. exit std::allocator<int>::allocator(std::allocator<int> const&) (./a.out
  18. exit std::_Vector_base<int, std::allocator<int> >::_Vector_impl::_Vector_impl(std::allocator<int> const&) (./a.out
  19. exit std::_Vector_base<int, std::allocator<int> >::_Vector_base(std::allocator<int> const&) (./a.out

上面我只貼出了部分信息,這顯然不是我們想要的,我們只想要顯示自定義的函數調用路徑,其他的都想要過濾掉,怎么辦?

這里可以將自定義的函數都加一個統一的前綴,在打印時只打印含有前綴的符號,這種個人認為是比較通用的方案。

下面是我過濾掉std和gnu子串的代碼:

  1. if (!strcasestr(name"std") && !strcasestr(name"gnu")) { 
  2.     printf("enter %s (%s)\n"name, info.dli_fname); 
  3.  
  4. if (!strcasestr(name"std") && !strcasestr(name"gnu")) { 
  5.     printf("exit %s (%s)\n"name, info.dli_fname); 

重新編譯后就會輸出我想要的結果:

  1. g++ test_trace.cc tracing.cc -std=c++14 -finstrument-functions -rdynamic -ldl;./a.out 
  2. 輸出:enter main (./a.out
  3. enter func() (./a.out
  4. enter func1() (./a.out
  5. exit func1() (./a.out
  6. exit func() (./a.out
  7. exit main (./a.out

還有一種方式是在編譯時使用下面的參數:

  1. -finstrument-functions-exclude-file-list 

它可以排除不想要做trace的文件,但是這個參數只在gcc中可用,在clang中卻不支持 ,所以上面的字符串過濾方式更通用一些。

上面只能拿到函數的名字,不能定位到具體的文件和行號,如果想要獲得更多信息,需要結合bfd系列參數(bfd_find_nearest_line)和libunwind一起使用,大家可以繼續研究。。。

tips1:這是一篇拋磚引玉的文章,本人不是后端開發,據我所知后端C++中有很多成熟的trace方案,大家有更好的方案可以留言,分享一波。

tips2:上面的方案可以達到鏈路追蹤的目的,但本人最后沒有應用到項目中,因為本人在做的項目對性能要求較高,使用此種方案會使整個SDK性能下降嚴重,無法滿足需求正常運行。于是暫時放棄了鏈路追蹤的這個想法。

本文的知識點還是值得了解一下的,大家或許會用得到。在研究的過程中我也發現了一個基于此種方案的開源項目(call-stack-logger),感興趣的也可以去了解了解。

 

責任編輯:武曉燕 來源: 程序喵大人
相關推薦

2023-10-16 23:43:52

云原生可觀測性

2023-01-30 22:34:44

Node.js前端

2022-07-22 07:59:17

日志方案

2022-05-23 08:23:24

鏈路追蹤SleuthSpring

2025-10-10 08:58:13

2022-05-19 13:33:39

系統客戶端鏈路追蹤

2024-12-16 13:34:35

2022-05-25 08:23:32

ZipKinTwitter開源項目

2025-03-11 14:16:09

2025-05-26 08:50:00

SLF4JMDC全鏈路追蹤

2024-09-06 12:24:19

2025-01-20 08:10:00

微服務架構SLF4J

2021-11-18 10:01:00

Istio 全鏈路灰度微服務框架

2022-12-05 19:15:12

得物云原生全鏈路

2018-07-03 15:56:59

騰訊

2022-09-15 10:03:42

Jaeger分布式追蹤系統

2023-08-24 22:13:31

2020-12-16 09:24:18

Skywalking分布式鏈路追蹤

2024-06-07 13:04:31

2024-01-05 00:29:36

全鏈路灰度發布云原生
點贊
收藏

51CTO技術棧公眾號

日韩aaaaa| 精品人妻人人做人人爽| 中文在线字幕免费观| 色喇叭免费久久综合| 91精品国产91热久久久做人人 | 亚洲成av人片在线观看无码| 精品一区二区国产| 中文在线字幕av| 亚洲大片在线| 自拍偷拍免费精品| 欲求不满的岳中文字幕| 欧美一级做a| 欧美日韩亚洲网| www.99riav| 77导航福利在线| 91在线视频播放| 成人免费视频网址| 国产精品第5页| 在线成人亚洲| 久久夜精品va视频免费观看| asian性开放少妇pics| 亚洲欧美日本国产| 欧美美女一区二区| 无遮挡又爽又刺激的视频| 快射视频在线观看| 国产日韩欧美激情| 九9re精品视频在线观看re6| 精品国自产在线观看| 美女网站在线免费欧美精品| 欧洲美女7788成人免费视频| 久草视频免费在线| 香港欧美日韩三级黄色一级电影网站| 亚洲精品一二区| 大尺度在线观看| 色悠久久久久综合先锋影音下载| 欧美影院午夜播放| 免费在线观看毛片网站| av成人福利| 亚洲一区二区三区美女| 成人高清dvd| 18加网站在线| 亚洲精品免费在线观看| 免费久久久久久| 免费a在线看| 国产精品美女一区二区三区| 日日骚一区二区网站| 免费在线观看污视频| 久久综合色播五月| 久久精品女人的天堂av| 污视频在线免费| av中文字幕不卡| 国产一区二区视频在线免费观看| 欧美 中文字幕| www.成人在线| 欧美午夜精品久久久久久蜜| 欧美女优在线| 国产欧美日本一区二区三区| 婷婷久久青草热一区二区| 极品美乳网红视频免费在线观看| 国产日韩欧美不卡| 亚洲va韩国va欧美va精四季| av电影在线观看一区二区三区| 国产精品免费人成网站| 亚洲国产一区在线| 黄色网页在线免费观看| 亚洲精品视频在线观看网站| 777久久精品一区二区三区无码| 在线观看小视频| 亚洲成av人综合在线观看| 秋霞无码一区二区| 桃子视频成人app| 欧美日韩五月天| 国产精品igao网网址不卡| 综合激情久久| 日韩国产中文字幕| 国产视频三区四区| 亚洲一区二区三区| 97精品一区二区视频在线观看| 国产三级av片| 老司机午夜精品99久久| 91超碰在线电影| 天堂成人在线| 国产精品理论片在线观看| 久久最新免费视频| 超碰97免费在线| 91久久精品一区二区二区| 日本不卡一区二区在线观看| 伊人久久大香线蕉av超碰| 日韩精品免费视频| 91香蕉视频污在线观看| 亚洲福利久久| 国产精品入口日韩视频大尺度| 国产模特av私拍大尺度| 99精品欧美一区二区蜜桃免费 | 91久久线看在观草草青青| av中文字幕网址| 伦理一区二区三区| 色777狠狠综合秋免鲁丝| 国产一级做a爱免费视频| 久久久精品网| 丁香婷婷久久久综合精品国产 | 国产白浆在线观看| 久久理论电影网| 中文字幕中文字幕一区三区| 多野结衣av一区| 欧美精选一区二区| 欧美图片一区二区| 欧美日韩亚洲一区| 国产精品嫩草影院久久久| 好吊色一区二区| 国产精品久久久久久久午夜片| 欧美精品卡一卡二| 国产日本亚洲| 中文字幕日本精品| 国内免费精品视频| 国产精品一卡二卡| 在线免费观看成人| 蜜桃精品在线| 亚洲老头老太hd| 精品一区二区三区人妻| 精品一区二区三区久久| 日本精品一区二区三区高清 久久 日本精品一区二区三区不卡无字幕 | 亚洲一区二区三区免费观看| 女厕盗摄一区二区三区| 日韩一二三区不卡| 日韩免费av一区| 日韩电影在线免费看| 久久精品第九区免费观看| 欧美人与动牲性行为| 91精品国产综合久久精品麻豆 | 亚洲图片欧美视频| 午夜剧场在线免费观看| 国产影视精品一区二区三区| 5566日本婷婷色中文字幕97| 欧美在线 | 亚洲| 一区二区三区在线视频观看58| 精品亚洲视频在线| 久久视频在线| 国产精品人成电影| 香蕉视频网站在线观看| 在线观看成人免费视频| 色婷婷在线影院| 六月天综合网| 日本在线播放不卡| 成人在线视频播放| 中文字幕av一区二区| 男操女视频网站| 中文字幕国产一区二区| 精品日韩久久久| 欧美精品一二| 国产日韩欧美影视| 26uuu亚洲电影在线观看| 日韩精品在线一区二区| 国产精品变态另类虐交| 99久久精品免费看| 成人观看免费完整观看| 免费视频国产一区| 国产精品免费一区二区三区都可以| 九色网友自拍视频手机在线| 欧美最新大片在线看| 蜜桃av免费观看| 激情久久五月天| 国产精品三级一区二区| 136国产福利精品导航网址应用| 高清亚洲成在人网站天堂| 天天影院图片亚洲| 欧美亚洲综合另类| 亚洲女人久久久| 国产寡妇亲子伦一区二区| aa视频在线播放| 欧美极品在线观看| 91久久久久久| 91九色porn在线资源| 亚洲精品综合久久中文字幕| 国产精品sm调教免费专区| 中文字幕中文字幕一区二区| 国产乱淫av麻豆国产免费| 99这里有精品| 亚洲一区三区| 国产精品115| 国产精品国产福利国产秒拍| 久久久久久国产精品免费无遮挡| 欧美精品一区二区三区蜜臀| 五月婷婷激情视频| 有坂深雪av一区二区精品| 国产一级二级在线观看| 久久精品国产99久久6| 国内少妇毛片视频| 欧美色婷婷久久99精品红桃| 1卡2卡3卡精品视频| 自拍一区在线观看| 久久久国产精品x99av | www.日韩视频| 亚洲三级黄色片| 欧美一区二区在线播放| 黄色在线视频网址| 亚洲另类在线视频| 国产精品亚洲无码| 国产成人亚洲综合a∨婷婷| 熟妇人妻va精品中文字幕| 国产精品theporn| 色噜噜狠狠一区二区三区| 久久丝袜视频| 亚洲free嫩bbb| 欧美日韩精品一区二区三区视频| 九九九久久久久久| eeuss影院www在线观看| 亚洲а∨天堂久久精品喷水| 又骚又黄的视频| 岛国av一区二区三区| 欧美成人精品激情在线视频| 中文字幕乱码久久午夜不卡| 一二三不卡视频| 不卡大黄网站免费看| 亚洲一二三av| 免费在线视频一区| 欧美精品自拍视频| 最新国产精品| 中文字幕色一区二区| 精品av一区二区| 免费影院在线观看一区| 精品福利一区| 亚洲综合第一页| aa亚洲一区一区三区| 国产精品露脸av在线| 日韩影片中文字幕| 欧美亚洲在线播放| caoporn视频在线| 欧美国产亚洲视频| 97caopor国产在线视频| 啊v视频在线一区二区三区| av在线天堂播放| 麻豆成人在线| 日本电影亚洲天堂| www.超碰在线| 久久久在线视频| 国产后进白嫩翘臀在线观看视频| 久久久99免费视频| 麻豆av在线导航| 久久久精品视频成人| 在线免费观看的av网站| 伊人久久大香线蕉av一区二区| 可以直接在线观看的av| 亚洲欧洲免费视频| 蜜桃免费在线| 一区二区三区视频免费在线观看| 撸视在线观看免费视频| 亚洲欧洲av一区二区| 九色蝌蚪在线| 综合av色偷偷网| 免费在线毛片网站| 久久天堂电影网| 手机在线免费av| 久久久久久久久久久国产| av福利在线导航| 欧美最顶级的aⅴ艳星| 超碰aⅴ人人做人人爽欧美| 国产成人中文字幕| av成人免费看| 91在线免费观看网站| 亚洲小说春色综合另类电影| 国产精品theporn88| 任我爽精品视频在线播放| 日本一区不卡| 亚洲电影影音先锋| 青草网在线观看| 亚洲一级在线| 天天操,天天操| 国模大尺度一区二区三区| 精品无码av一区二区三区不卡| 粉嫩av亚洲一区二区图片| 800av在线播放| 国产清纯白嫩初高生在线观看91| 午夜成人亚洲理伦片在线观看| 亚洲专区一二三| 亚洲自拍一区在线观看| 欧美福利视频导航| 日韩一级片免费观看| 亚洲欧美日韩中文视频| 国产传媒在线播放| 91精品国产色综合久久不卡98| www.久久.com| 国产精品国色综合久久| 中文字幕精品影院| 老司机av福利| 亚洲欧美日韩国产综合精品二区| 天天爽天天爽夜夜爽| 国产风韵犹存在线视精品| 久久精品成人av| 一区二区三区在线免费播放| 亚洲欧美自拍视频| 欧美一区二区在线播放| 免费在线性爱视频| 久久99久久99精品免观看粉嫩| 裤袜国产欧美精品一区| 91原创国产| 日韩aaaa| 国产午夜伦鲁鲁| 国产精品亚洲一区二区三区在线| 91中文字幕永久在线| 亚洲一区国产视频| 中文字幕男人天堂| 亚洲精品美女在线| gogogogo高清视频在线| 国产精品久久久久久久美男 | 日韩毛片在线播放| 欧美日本一道本| 亚洲欧美综合在线观看| 不卡av电影院| 欧美videos粗暴| 欧美精品成人一区二区在线观看| 中文字幕免费一区二区| 国产又猛又黄的视频| eeuss影院一区二区三区 | 欧美久久综合| 鲁一鲁一鲁一鲁一av| 91一区二区三区在线观看| 加勒比av在线播放| 51精品国自产在线| av免费在线一区二区三区| 性日韩欧美在线视频| 日韩三级久久| 一区二区三区四区免费观看| 蜜臀av亚洲一区中文字幕| 中文字幕国产专区| 欧美日韩日本国产| 欧美视频xxx| 海角国产乱辈乱精品视频| 精品国产三区在线| 在线成人性视频| 另类小说欧美激情| 国产馆在线观看| 欧美蜜桃一区二区三区| porn亚洲| 国产日韩中文字幕在线| 久久综合国产| 亚洲视频一二三四| 国产精品久久久久久久久快鸭| 姑娘第5集在线观看免费好剧| 亚洲精品一区二区三区婷婷月 | 91久久在线视频| 久久精品高清| 伊人色在线观看| 亚洲男同1069视频| 国产xxxx孕妇| 国精产品一区一区三区有限在线| 91成人福利| 久久久999免费视频| 2023国产精品自拍| 久久久精品视频网站| 亚洲欧美中文字幕| 91精品国产经典在线观看| 亚洲人成网站在线观看播放| 欧美aaaaaa午夜精品| 99热这里只有精品4| 欧美肥妇毛茸茸| 在线电影福利片| 国产精品视频福利| 国产精品最新自拍| 国产激情av在线| 91精品国产一区二区三区| 日韩伦理电影网站| 精品国产乱码久久久久| 天堂成人免费av电影一区| 免费一级特黄3大片视频| 91 com成人网| 99热99re6国产在线播放| 欧美精品v日韩精品v国产精品| 日本少妇一区二区| 99久久婷婷国产综合| 欧美精品一区二区三区一线天视频 | 亲子乱一区二区三区电影| 精品久久精品| 久久久久久国产精品日本| 天天亚洲美女在线视频| 国产裸舞福利在线视频合集| 成人激情视频在线| 影音先锋亚洲一区| 久久久久久久久久久久久久久| 欧美精品精品一区| 高h视频在线播放| 深田咏美在线x99av| 国产精品亚洲专一区二区三区| www.国产色| 久久久99免费视频| 日韩精品丝袜美腿| www.午夜av| 欧美日韩国产在线看| 免费黄网在线观看| 久久精品国产精品国产精品污| 加勒比av一区二区| 亚洲另类欧美日韩| 久热精品在线视频| 你懂的视频欧美| 久久精品无码专区| 欧美日韩成人一区| 夜鲁夜鲁夜鲁视频在线播放| 手机看片日韩国产| 国产欧美一区视频| 神马午夜在线观看|