国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

C++源碼調用圖生成器實現

oysun / 2362人閱讀

摘要:前言之前受知乎用戶啟發,寫了個源碼的調用圖生成器,可以以圖示法顯示函數的調用關系,代碼放在了倉庫里,僅供參考主要思路利用的的注入選項,得到每個函數的調用地址信息,生成一個文件,然后利用和將函數名及其所在源碼位置從地址中解析出來,從而得到

前言

之前受知乎用戶mailto1587啟發,寫了個C++源碼的調用圖生成器,可以以圖示法顯示C++函數的調用關系,
代碼放在了github倉庫里,僅供參考:
CodeSnippet/python/SRCGraphviz/c++ at master · Cheukyin/CodeSnippet · GitHub

主要思路

利用gcc/g++-finstrument-functions的注入選項,
得到每個函數的調用地址信息,生成一個trace文件
然后利用addr2linec++filt函數名及其所在源碼位置從地址中解析出來,
從而得到程序的Call Stack
然后用pygraphviz畫出來

使用示例

比如我現在有A.hppB.hppC.hppABCTest.cpp這幾個文件,
我想看他們的Call Graph

源碼如下:

然后按下面編譯(instrument.c在上面github地址中可以下載,用于注入地址信息):
g++ -g -finstrument-functions -O0 instrument.c ABCTest.cpp -o test
然后運行程序,得到trace.txt
輸入shell命令./test
最后
輸入shell命令python CallGraph.py trace.txt test
彈出一張Call Graph

圖上標注含義:

綠線表示程序啟動后的第一次調用

紅線表示進入當前上下文的最后一次調用

每一條線表示一次調用,#符號后面的數字是序號,at XXX表示該次調用發生在這個文件(文件路徑在框上方)的第幾行

在圓圈里,XXX:YYYYYY是調用的函數名,XXX表示這個函數是在該文件的第幾行被定義的

獲取C/C++調用關系

利用-finstrument-functions編譯選項,
可以讓編譯器在每個函數的開頭和結尾注入__cyg_profile_func_enter__cyg_profile_func_exit
這兩個函數的實現由用戶定義

在本例中,只用到__cyg_profile_func_enter,定義在instrument.c中,
其函數原型如下:
void __cyg_profile_func_enter (void *this_fn, void *call_site);
其中this_fn為 被調用的地址,call_site為 調用方的地址

顯然,假如我們把所有的 調用方和被調用方的地址 都打印出來,
就可以得到一張完整的運行時Call Graph

因此,我們的instrument.c實現如下:

/* Function prototypes with attributes */
void main_constructor( void )
    __attribute__ ((no_instrument_function, constructor));

void main_destructor( void )
    __attribute__ ((no_instrument_function, destructor));

void __cyg_profile_func_enter( void *, void * )
    __attribute__ ((no_instrument_function));

void __cyg_profile_func_exit( void *, void * )
    __attribute__ ((no_instrument_function));

static FILE *fp;

void main_constructor( void )
{
  fp = fopen( "trace.txt", "w" );
  if (fp == NULL) exit(-1);
}

void main_deconstructor( void )
{
  fclose( fp );
}

void __cyg_profile_func_enter( void *this_fn, void *call_site )
{
    /* fprintf(fp, "E %p %p
", (int *)this_fn, (int *)call_site); */
    fprintf(fp, "%p %p
", (int *)this_fn, (int *)call_site);
}

其中main_constructor在 調用main 前執行,main_deconstructor在調用main后執行,
以上幾個函數的作用就是 將所有的 調用方和被調用方的地址 寫入trace.txt

然而,現在有一個問題,就是trace.txt中保存的是地址,我們如何將地址翻譯成源碼中的符號?
答案就是用addr2line

以上面ABCTest.cpp工程為例,比如我們現在有地址0x400974,輸入以下命令
addr2line 0x400aa4 -e a.out -f
結果為

_ZN1A4AOneEv
/home/cheukyin/PersonalProjects/CodeSnippet/python/SRCGraphviz/c++/A.hpp:11

第一行該地址所在的函數名,第二行為函數所在的源碼位置

然而,你一定會問,_ZN1A4AOneEv是什么鬼?
為實現重載、命名空間等功能,因此C++name mangling,因此函數名是不可讀的

我們需要利用c++filt作進一步解析:
輸入shell命令 addr2line 0x400aa4 -e a.out -f | c++filt
結果是不是就清晰很多:

A::AOne()
/home/cheukyin/PersonalProjects/CodeSnippet/python/SRCGraphviz/c++/A.hpp:11

注意這個結果中包含了函數名、函數所在文件和行號

調用圖渲染

經過上面的步驟,我們已經可以把所有的(調用方, 被調用方)對分析出來了,相當于獲取到調用圖所有的節點和邊,
最后可以用pygraphviz將 每一條調用關系 畫出來即可,代碼用python實現在 CallGraph.py 中

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/38409.html

相關文章

  • 基于Linux環境搭建Nginx+uWSGI+Python框架方法介紹

    摘要:目前在和平臺下使用最廣泛的免費服務器有和。涉及到普通用戶執行命令時權限不足的問題,可在命令前增加指令解決。是基于二進制的線路協議,與協議作用相同,但屬于服務器自有協議是服務器,它實現了協議等協議安裝。 前言 瀏覽器上網的過程簡單來說即是瀏覽器從服務器中獲取網站信息,經過渲染后將效果呈現給用戶。這里側重介紹下在幕后默默工作著的服務器。Web服務器是運行在物理服務器上的一個程序,永久地等待...

    spacewander 評論0 收藏0
  • 基于Linux環境搭建Nginx+uWSGI+Python框架方法介紹

    摘要:目前在和平臺下使用最廣泛的免費服務器有和。涉及到普通用戶執行命令時權限不足的問題,可在命令前增加指令解決。是基于二進制的線路協議,與協議作用相同,但屬于服務器自有協議是服務器,它實現了協議等協議安裝。 前言 瀏覽器上網的過程簡單來說即是瀏覽器從服務器中獲取網站信息,經過渲染后將效果呈現給用戶。這里側重介紹下在幕后默默工作著的服務器。Web服務器是運行在物理服務器上的一個程序,永久地等待...

    whataa 評論0 收藏0
  • javascript引擎——V8

    摘要:類將源代碼解釋并構建成抽象語法樹,使用類來創建它們,并使用類來分配內存。類抽象語法樹的訪問者類,主要用來遍歷抽象語法樹。在該函數中,先使用類來生成抽象語法樹再使用類來生成本地代碼。 通過上一篇文章,我們知道了JavaScript引擎是執行JavaScript代碼的程序或解釋器,了解了JavaScript引擎的基本工作原理。我們經常聽說的JavaScript引擎就是V8引擎,這篇文章我們...

    luoyibu 評論0 收藏0
  • JavaScript 工作原理之六-WebAssembly 對比 JavaScript 及其使用場景

    摘要:現在,我們將會剖析的工作原理,而最重要的是它和在性能方面的比對加載時間,執行速度,垃圾回收,內存使用,平臺訪問,調試,多線程以及可移植性。目前,是專門圍繞和的使用場景設計的。目前不支持多線程。 原文請查閱這里,略有改動,本文采用知識共享署名 4.0 國際許可協議共享,BY Troland。 本系列持續更新中,Github 地址請查閱這里。 這是 JavaScript 工作原理的第六章...

    jay_tian 評論0 收藏0

發表評論

0條評論

oysun

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<