新聞中心
動(dòng)態(tài)庫(kù)是在程序運(yùn)行時(shí)才被載入的,可以大大減小程序體積,提高程序運(yùn)行速度的鏈接庫(kù)。在Linux下,我們可以使用一些工具來(lái)測(cè)試動(dòng)態(tài)庫(kù)接口,以確保其正確性和可靠性。本文將介紹一些常用的Linux下動(dòng)態(tài)庫(kù)接口測(cè)試工具和測(cè)試方法,并提供一些簡(jiǎn)易指南,幫助初學(xué)者更好地進(jìn)行動(dòng)態(tài)庫(kù)接口測(cè)試。

鹽湖ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書(shū)未來(lái)市場(chǎng)廣闊!成為創(chuàng)新互聯(lián)的ssl證書(shū)銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書(shū)合作)期待與您的合作!
一、動(dòng)態(tài)庫(kù)接口測(cè)試概述
動(dòng)態(tài)庫(kù)接口測(cè)試是測(cè)試動(dòng)態(tài)庫(kù)是否能夠正確地鏈接和使用,以及是否具有預(yù)期的功能和行為。動(dòng)態(tài)庫(kù)接口包括函數(shù)名、參數(shù)類型、返回類型等,它們必須與其他應(yīng)用程序或庫(kù)的接口嚴(yán)格匹配,否則就會(huì)出現(xiàn)鏈接錯(cuò)誤或運(yùn)行時(shí)錯(cuò)誤。
動(dòng)態(tài)庫(kù)接口測(cè)試的目的是驗(yàn)證應(yīng)用程序或庫(kù)能夠成功地調(diào)用動(dòng)態(tài)庫(kù)的接口,并且處理不同的輸入和異常情況時(shí)能夠正確地響應(yīng)。測(cè)試用例應(yīng)涵蓋所有的接口函數(shù)和參數(shù)類型,并包括相關(guān)的邊界條件和異常情況。
二、常用的動(dòng)態(tài)庫(kù)接口測(cè)試工具
1. ldd
ldd命令用來(lái)列出一個(gè)動(dòng)態(tài)庫(kù)所依賴的其他庫(kù),可以用來(lái)檢查動(dòng)態(tài)庫(kù)的依賴關(guān)系和版本信息,以保證程序能夠正確鏈接并運(yùn)行。
例如:
“`
$ ldd libtest.so
libstdc++.so.6 => /usr/lib64/libstdc++.so.6 (0x00007fd40a29d000)
libm.so.6 => /lib64/libm.so.6 (0x00007fd409f2f000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fd409d17000)
libc.so.6 => /lib64/libc.so.6 (0x00007fd40994e000)
/lib64/ld-linux-x86-64.so.2 (0x00007fd40a6bb000)
“`
2. nm
nm命令用來(lái)顯示動(dòng)態(tài)庫(kù)中包含的符號(hào)列表,包括函數(shù)名、變量名和其他符號(hào)等,可以用來(lái)檢查動(dòng)態(tài)庫(kù)中的接口是否正確定義和實(shí)現(xiàn)。
例如:
“`
$ nm libtest.so
U _ZNSt7__cxx1112basic_stringIcSt11char_trtsIcESaIcEEC1Ev
00000000000010e0 T func1
0000000000001140 T func2
U puts@@GLIBC_2.2.5
U strlen@@GLIBC_2.2.5
U std::__cxx11::basic_string, std::allocator >::size() const
“`
3. objdump
objdump命令用于查看二進(jìn)制文件的指令、符號(hào)、重定向表和其他信息??梢杂胦bjdump命令來(lái)檢查動(dòng)態(tài)庫(kù)的接口是否正確實(shí)現(xiàn)、是否存在潛在的安全漏洞等。
例如:
“`
$ objdump -T libtest.so
libtest.so: file format elf64-x86-64
DYNAMIC SYMBOL TABLE:
0000000000000000 D *UND* 0000000000000000 GLIBC_2.2.5 puts
0000000000000000 D *UND* 0000000000000000 GLIBC_2.2.5 strlen
0000000000000000 w D *UND* 0000000000000000 __gmon_start__
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_mn
0000000000001020 g DF .text 0000000000000020 Base func1
0000000000001080 g DF .text 0000000000000020 Base func2
0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize
“`
4. gdb
gdb是GNU調(diào)試器,可以用來(lái)調(diào)試動(dòng)態(tài)庫(kù)中的函數(shù),查找并修復(fù)相關(guān)的錯(cuò)誤和故障。
例如:
“`
$ gdb ./test
(gdb) b func1
(gdb) r
(gdb) step
(gdb) p ret
$1 = 10
(gdb) step
(gdb) p ret
$2 = 20
(gdb) q
“`
五、動(dòng)態(tài)庫(kù)接口測(cè)試方法
動(dòng)態(tài)庫(kù)接口測(cè)試方法包括手動(dòng)測(cè)試和自動(dòng)測(cè)試兩種。手動(dòng)測(cè)試是通過(guò)手工執(zhí)行測(cè)試用例來(lái)檢查動(dòng)態(tài)庫(kù)接口的正確性和可靠性;而自動(dòng)測(cè)試則是通過(guò)一些工具來(lái)自動(dòng)化執(zhí)行測(cè)試用例和檢查測(cè)試結(jié)果。
1. 手動(dòng)測(cè)試
手動(dòng)測(cè)試需要編寫測(cè)試用例并對(duì)其進(jìn)行手工執(zhí)行,以模擬不同的輸入和異常情況,并檢查測(cè)試結(jié)果是否與預(yù)期相符。
例如:
測(cè)試用例1:測(cè)試func1函數(shù)的功能和正確性
“`
#include
#include “l(fā)ibtest.h”
int mn() {
int ret1, ret2, expect1, expect2;
ret1 = func1(2, 3);
expect1 = 5;
if (ret1 != expect1) {
printf(“func1 test fled: expect %d, but got %d\n”, expect1, ret1);
}
ret2 = func1(-2, 3);
expect2 = 1;
if (ret2 != expect2) {
printf(“func1 test fled: expect %d, but got %d\n”, expect2, ret2);
}
return 0;
}
“`
測(cè)試用例2:測(cè)試func2函數(shù)的功能和正確性
“`
#include
#include “l(fā)ibtest.h”
int mn() {
const char* str = “hello”;
int ret1, ret2, expect1, expect2;
ret1 = func2(str);
expect1 = 5;
if (ret1 != expect1) {
printf(“func2 test fled: expect %d, but got %d\n”, expect1, ret1);
}
ret2 = func2(NULL);
expect2 = -1;
if (ret2 != expect2) {
printf(“func2 test fled: expect %d, but got %d\n”, expect2, ret2);
}
return 0;
}
“`
2. 自動(dòng)測(cè)試
自動(dòng)測(cè)試需要使用一些測(cè)試框架來(lái)自動(dòng)化執(zhí)行測(cè)試用例和檢查測(cè)試結(jié)果。常用的測(cè)試框架包括Google Test、CUnit等。
例如:
使用Google Test測(cè)試框架進(jìn)行自動(dòng)測(cè)試
“`
#include
#include “l(fā)ibtest.h”
TEST(Func1Test, PositiveTest) {
EXPECT_EQ(5, func1(2, 3));
}
TEST(Func1Test, NegativeTest) {
EXPECT_EQ(1, func1(-2, 3));
}
TEST(Func2Test, PositiveTest) {
const char* str = “hello”;
EXPECT_EQ(5, func2(str));
}
TEST(Func2Test, NegativeTest) {
EXPECT_EQ(-1, func2(NULL));
}
int mn(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
“`
六、
動(dòng)態(tài)庫(kù)接口測(cè)試是確保動(dòng)態(tài)庫(kù)正確性和可靠性的重要步驟。在Linux下,我們可以使用一些工具來(lái)測(cè)試動(dòng)態(tài)庫(kù)接口,包括ldd、nm、objdump和gdb等。同時(shí),手動(dòng)測(cè)試和自動(dòng)測(cè)試也是動(dòng)態(tài)庫(kù)接口測(cè)試的兩種常用方法,可以根據(jù)不同的需求選擇適合自己的測(cè)試方法。
相關(guān)問(wèn)題拓展閱讀:
- 請(qǐng)教關(guān)于android linux動(dòng)態(tài)庫(kù).so的加載調(diào)用
- 如何判斷l(xiāng)inux 動(dòng)態(tài)庫(kù)調(diào)用
請(qǐng)教關(guān)于android linux動(dòng)態(tài)庫(kù).so的加載調(diào)用
1、 .so動(dòng)態(tài)庫(kù)的生成
可使用gcc或者g++編譯器生成動(dòng)態(tài)庫(kù)文件(此處以g++編譯器為例)
g++ -shared -fPIC -c XXX.cpp
g++ -shared -fPIC -o XXX.so XXX.o
2、 .so動(dòng)態(tài)庫(kù)的動(dòng)態(tài)調(diào)用接口函數(shù)說(shuō)明
動(dòng)態(tài)庫(kù)的調(diào)用關(guān)系可以在需要調(diào)用動(dòng)態(tài)庫(kù)的程序編譯時(shí),通過(guò)g++的-L和-l命令來(lái)指定。例如:程序test啟動(dòng)時(shí)需要加載目錄/root/src/lib中的libtest_so1.so動(dòng)態(tài)庫(kù),編譯命令可照如下編寫執(zhí)行:
g++ -g -o test test.cpp –L/root/src/lib –ltest_so1
(此處,我們重點(diǎn)講解動(dòng)態(tài)庫(kù)的動(dòng)態(tài)調(diào)用的方法,關(guān)于靜態(tài)的通過(guò)g++編譯命令調(diào)用的方式不作詳細(xì)講解,具體相關(guān)內(nèi)容可上網(wǎng)查詢)
Linux下,提供專門的一組API用于完成打開(kāi)動(dòng)態(tài)庫(kù)慧蘆,查找符號(hào),處理出錯(cuò),關(guān)閉動(dòng)態(tài)庫(kù)等功能。
下面對(duì)這些接口函數(shù)逐一介紹(調(diào)用這些接口時(shí),需引用頭文件#include ):
1)dlopen
函數(shù)原型:void *dlopen(const char *libname,int flag);
功能描述:dlopen必須在dlerror,dlsym和dlclose之前調(diào)用,表示要將庫(kù)裝載到內(nèi)存,準(zhǔn)備使用。如果要裝載的庫(kù)依賴于其它庫(kù),必須首先裝載依賴庫(kù)。如果dlopen操作失敗,返回NULL值;如果庫(kù)已經(jīng)被裝載過(guò),則dlopen會(huì)返回同樣的句柄。
參數(shù)中的libname一般是庫(kù)的全路徑,這樣dlopen會(huì)直接裝載該文件;如果只是指定了庫(kù)名稱,在dlopen會(huì)按照下面的機(jī)制去搜尋:
a.根據(jù)環(huán)境變量LD_LIBRARY_PATH查找
b.根據(jù)/etc/ld.so.cache查找
c.查找依次在/lib和/usr/lib目錄查找。
flag參數(shù)表示處理未定義函數(shù)的方式,可以使用RTLD_LAZY或RTLD_NOW。RTLD_LAZY表示暫時(shí)不去處理未定義函數(shù),迅搜先把庫(kù)裝載到內(nèi)存,等用到?jīng)]定義的函數(shù)再說(shuō);RTLD_NOW表示馬上檢查是否存在未定義的函數(shù),若存在,則dlopen以失敗告終。
2)dlerror
函數(shù)原型:char *dlerror(void);
功能描述:dlerror可以獲得最近一次dlopen,dlsym或dlclose操作的錯(cuò)誤信息,返回NULL表示無(wú)錯(cuò)誤。dlerror在返回錯(cuò)誤信息的同時(shí),也會(huì)清除錯(cuò)誤信息。
3)dlsym
函數(shù)原型:void *dlsym(void *handle,const char *symbol);
功能描述:在dlopen之后,庫(kù)被裝載到內(nèi)存。dlsym可以獲得指定函數(shù)(symbol)在內(nèi)前昌帶存中的位置(指針)。如果找不到指定函數(shù),則dlsym會(huì)返回NULL值。但判斷函數(shù)是否存在更好的方法是使用dlerror函數(shù),
4)dlclose
函數(shù)原型:int dlclose(void *);
功能描述:將已經(jīng)裝載的庫(kù)句柄減一,如果句柄減至零,則該庫(kù)會(huì)被卸載。如果存在析構(gòu)函數(shù),則在dlclose之后,析構(gòu)函數(shù)會(huì)被調(diào)用。
3、 普通函數(shù)的調(diào)用
此處以源碼實(shí)例說(shuō)明。各源碼文件關(guān)系如下:
test_so1.h和test_so1.cpp生成test_so1.so動(dòng)態(tài)庫(kù)。
test_so2.h和test_so2.cpp生成test_so2.so動(dòng)態(tài)庫(kù)。
test_dl.cpp生成test_dl可執(zhí)行程序,test_dl通過(guò)dlopen系列等API函數(shù),并使用函數(shù)指針以到達(dá)動(dòng)態(tài)調(diào)用不同so庫(kù)中test函數(shù)的目的。
如何判斷l(xiāng)inux 動(dòng)態(tài)庫(kù)調(diào)用
創(chuàng)建靜態(tài)庫(kù):
ar -rcs test.a *.o
查看靜態(tài)庫(kù):
ar -tv test.a
解壓靜態(tài)庫(kù):
ar -x test.a
查看程序依賴的動(dòng)態(tài)庫(kù):
readelf -a xxx|grep library
如:可以看到,下面的交饑賀叉程序hello執(zhí)行依賴于如下兩個(gè)動(dòng)態(tài)庫(kù)。
rebi@ubuntu:~/test$ arm-none-linux-gnueabi-readelf -a hello|grep “l(fā)ibrary”
0x(NEEDED)Shared library:
0x(NEEDED)Shared library:
rebi@ubuntu:~/test$
或者跡嘩:readelf -l hello 即可。
nm xxx 查看符號(hào)
關(guān)于linux測(cè)試動(dòng)態(tài)庫(kù)接口的介紹到此就結(jié)束了,不知道你從中找到你需要的信息了嗎 ?如果你還想了解更多這方面的信息,記得收藏關(guān)注本站。
成都網(wǎng)站設(shè)計(jì)制作選創(chuàng)新互聯(lián),專業(yè)網(wǎng)站建設(shè)公司。
成都創(chuàng)新互聯(lián)10余年專注成都高端網(wǎng)站建設(shè)定制開(kāi)發(fā)服務(wù),為客戶提供專業(yè)的成都網(wǎng)站制作,成都網(wǎng)頁(yè)設(shè)計(jì),成都網(wǎng)站設(shè)計(jì)服務(wù);成都創(chuàng)新互聯(lián)服務(wù)內(nèi)容包含成都網(wǎng)站建設(shè),小程序開(kāi)發(fā),營(yíng)銷網(wǎng)站建設(shè),網(wǎng)站改版,服務(wù)器托管租用等互聯(lián)網(wǎng)服務(wù)。
標(biāo)題名稱:Linux下動(dòng)態(tài)庫(kù)接口測(cè)試簡(jiǎn)易指南 (linux測(cè)試動(dòng)態(tài)庫(kù)接口)
URL地址:http://www.dlmjj.cn/article/cdespgo.html


咨詢
建站咨詢
