當前位置:首頁 » 編程軟體 » 編譯打樁

編譯打樁

發布時間: 2023-06-14 11:58:33

① 你在編程中寫過最多的代碼是什麼

java的時候,我想我寫的最多的一句話是System.out.println();在後台列印出變數的值,判斷傳進去的參數或處理的數據是否正確。其實寫java的時候,最不喜歡的就是調試,後來接觸到ruby可以實時查看結果不用重啟伺服器,再回來寫java時,那個麻煩啊,重新編譯重新部署,總要耗費你一段時間,這個時間之前倒沒覺得有多痛苦。

php打樁是什麼意思

PHP打樁演算法

打樁是一種用定製的函數替換鏈接庫函數且不需重新編譯的技術。甚至可用此技術替換系統調用(更確切地說,庫函數包裝系統調用)。可能的應用是沙盒、調試或性能優化庫。為演示過程,此處給出一個簡單庫,以記錄GNU/Linux中
malloc 調用次數。

/*_GNU_SOURCEisneededforRTLD_NEXT,GCCwillnotdefineitbydefault*/
#define_GNU_SOURCE
#include<stdio.h>
#include<stdlib.h>
#include<dlfcn.h>
#include<stdint.h>
#include<inttypes.h>

staticuint32_tmalloc_count=0;
staticuint64_ttotal=0;

voidsummary(){
fprintf(stderr,"malloccalled:%utimes ",count);
fprintf(stderr,"totalallocatedmemory:%"PRIu64"bytes ",total);
}

void*malloc(size_tsize){
staticvoid*(*real_malloc)(size_t)=NULL;
void*ptr=0;

if(real_malloc==NULL){
real_malloc=dlsym(RTLD_NEXT,"malloc");
atexit(summary);
}

count++;
total+=size;

returnreal_malloc(size);
}

打樁祥皮要在鏈接libc.so之前載入此庫,這樣我們的 malloc 實現就會在二進制文件執行時被鏈接。可通過設置 LD_PRELOAD
環境變數為我們想讓鏈接器優先鏈接的全路徑。這也能確保其他動態鏈接庫的調用最終使用我們的 malloc
實現。因為我們的目標只是記錄調用次數,不是真正地實現內存分配,所以我們仍需要調用「真正」的 malloc 。通過傳遞 RTLD_NEXT 偽處理程序到
dlsym,我們獲得了指向下一個已載入的鏈接庫中 malloc 事件的指針。第一次 malloc 調用 libc 的 malloc,當程序終止時,會調用由
atexit 注冊的獲取和 summary 函數。看GNU/Linxu中打樁行為(真的184次調用!):

$gcc-shared-ldl-fPICmalloc_counter.c-o/tmp/libmcnt.so
$exportLD_PRELOAD="/tmp/libstr.so"
$ps
PIDTTYTIMECMD
2758pts/200:00:00bash
4371pts/200:00:00ps
malloccalled:184times
totalallocatedmemory:302599bytes

下面來看下PHP打樁演算法在使用時出現的問題。

當構造測試用例的數據,是在函數內部被另一個外部函數所使用時,我們需要忽略外部函數所帶來的影響。

需要進行「打樁」,舉一個具體的例子

classDataGetter{
public:
...
boolRun();
...
private:
...
Client*m_ptr_client;
...
};
.....
.....
boolDataGetter::Run(){
...
std::stringdata;
boolret=m_ptr_client->GetData(data);
...
}
....
....

比如要對run這個函數進行單元測試,它內部調用了ptr_client->GetData(data)的方法,它是通過tcp協議從服務端取數據到data里,測試run這個函數,必然要構造data。

如果不「打樁」,要測試的話,我們就需要再從服務端去構造數據,而且還可能收到其他因素的影響。

這時候「樁」就是很好的一種技術。

那如何去構造「樁」呢。

那麼如何構造呢?

原理:利用c++ virtual的特性,改變m_ptr_client指針所指向的對象,重寫一個「打樁」測試類。

當然,前提是GetData的定謹橋差義本身是virtual的消宏。

假設Client的定義如下

classClient{
......
public:
virtualboolGetData(std::string&data);
......
};

我們只需要重寫Getdata的方法,並且當參數data被傳進來時,我們可以返回特定的值。

這一套方法,google已經提供了很好的一套框架:gmock

下面介紹一下它的用法

#include"client.h"//被mock的類的頭文件
#include//gmock的頭文件
classMockClient:publicClient{
public:
MockClient():Client(){}
MOCK_METHOD1(GetData,bool(std::string&));
}

這里使用了一個宏MOCK_METHOD1

原形是MOCK_METHOD#1(#2, #3(#4) )

#1表示被mock的函數參數個數,#2表示被mock的函數名稱,#3表示被mock的函數返回值,#4表示被mock的函數參數列表

這樣,一個「樁」就「打」好了。

如何正確簡便地使用

首先,要先改變m_ptr_client指向的對象,對於private的變數,在前一章有描述方法,

然後測試的時候,直接將 m_ptr_client = new
MockClient()即可,不過要記得釋放它之前new的資源(如果有的話),不然就內存泄露了,哈哈

使用gmock的幾個宏,用一個例子簡單介紹下:

EXPECT_CALL(//mock被調用時,要發生的動作
*m_ptr_client,//被mock的對象,看清楚,是對象,不是指針了
GetData(test::_)//被mock的方法,參數為佔位符
).Times(2)//表示被調用2次
.WillOnce(第一次調用
testing::SetArgReferee<0>(「test」),//設置第0個參數的值為「test」
testing::Return(true),//設置返回值為true
)
.WillOnce(第二次調用
testing::SetArgReferee<0>(「test」),//設置第0個參數的值為「test」
testing::Return(false),//設置返回值為false
);

測試的原則,盡量不修改被測函數,覆蓋函數的每一個分支,保證外部條件都是正確的。

熱點內容
美國雲伺服器快還是香港快 發布:2025-02-09 09:34:33 瀏覽:988
怎麼解壓qq文件 發布:2025-02-09 09:18:14 瀏覽:581
安卓最新怎麼調靈敏度更穩 發布:2025-02-09 09:12:44 瀏覽:400
豌豆莢如何用安卓手機下載 發布:2025-02-09 09:11:57 瀏覽:213
吃雞腳本輔助 發布:2025-02-09 09:09:29 瀏覽:6
sessionidpython 發布:2025-02-09 09:08:53 瀏覽:276
華為手機驗證碼和密碼忘了是多少 發布:2025-02-09 08:53:53 瀏覽:799
逆戰筆記哪個配置好玩 發布:2025-02-09 08:53:04 瀏覽:600
怎麼打開電腦雲伺服器 發布:2025-02-09 08:36:01 瀏覽:220
日元對人民幣演算法 發布:2025-02-09 08:35:52 瀏覽:40