本發(fā)明涉及通信領(lǐng)域,具體而言,涉及一種函數(shù)調(diào)用信息的獲取方法及裝置、測試設(shè)備。
背景技術(shù):
相關(guān)技術(shù)中提供了一種可以記錄托管代碼函數(shù)的調(diào)用情況的技術(shù)方案,利用Mono提供的Profiler(可以理解為是一種分析工具)功能,該功能可以利用Mono提供的mono_profiler_install_enter_leave接口注冊兩個函數(shù),這兩個注冊過的回調(diào)函數(shù)分別會在托管代碼里的函數(shù)進(jìn)入和退出的時候被調(diào)用,Mono會給這兩個回調(diào)函數(shù)提供一個自定義的數(shù)據(jù)結(jié)構(gòu),用來存儲可能需要的數(shù)據(jù),還會提供一個參數(shù),通過該參數(shù)可以獲取本次托管代碼調(diào)用了哪個函數(shù)。接口注冊好了以后再用Mono提供的mono_profiler_set_events接口設(shè)置MONO_PROFILER_ENTER_LEAVE事件,至此,托管代碼中運(yùn)行的所有函數(shù)只要一被執(zhí)行就會調(diào)用注冊過的兩個回調(diào)函數(shù)。
在實(shí)際項目中,發(fā)明人發(fā)現(xiàn)使用上述技術(shù)方案去記錄托管代碼函數(shù)的調(diào)用情況,會發(fā)生偶現(xiàn)的crash崩潰現(xiàn)象,直接導(dǎo)致了現(xiàn)有的技術(shù)方案不能應(yīng)用在一些復(fù)雜項目中。
針對上述的問題,目前尚未提出有效的解決方案。
技術(shù)實(shí)現(xiàn)要素:
本發(fā)明實(shí)施例提供了一種函數(shù)調(diào)用信息的獲取方法及裝置、測試設(shè)備,以至少解決相關(guān)技術(shù)中采用mono提供的分析工具獲取托管函數(shù)的調(diào)用情況的技術(shù)方案,偶現(xiàn)crash現(xiàn)象的技術(shù)問題。
根據(jù)本發(fā)明實(shí)施例的一個方面,提供了一種函數(shù)調(diào)用信息的獲取方法,包括:
在運(yùn)行待測試的程序的過程中,對所述程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),其中,所述非托管函數(shù)被允許直接運(yùn)行在中央處理器CPU上;對所述非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,其中,所述hook操作用于監(jiān)控所述非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,所述第一函數(shù)調(diào)用信息至少包括:函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;根據(jù)所述第一函數(shù)調(diào)用信息和所述托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,其中,所述第二函數(shù)調(diào)用信息中包括具有對應(yīng)關(guān)系的所述托管函數(shù)的函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;輸出所述第二函數(shù)調(diào)用信息。
根據(jù)本發(fā)明的另一個方面,還提供了一種函數(shù)調(diào)用信息的獲取裝置,包括:
編譯單元,用于在運(yùn)行待測試的程序的過程中,對所述程序中待調(diào)用的托管函數(shù)進(jìn)行編譯;第一確定單元,用于對所述托管函數(shù)編譯后得到非托管函數(shù),其中,所述非托管函數(shù)被允許直接運(yùn)行在中央處理器CPU上;第二確定單元,用于對所述非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,其中,所述hook操作用于監(jiān)控所述非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,所述第一函數(shù)調(diào)用信息至少包括:函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;生成單元,用于根據(jù)所述第一函數(shù)調(diào)用信息和所述托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,其中,所述第二函數(shù)調(diào)用信息中包括具有對應(yīng)關(guān)系的所述托管函數(shù)的函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;輸出單元,用于輸出所述第二函數(shù)調(diào)用信息。
根據(jù)本發(fā)明實(shí)施例的另一方面,還提供了一種測試設(shè)備,包括:處理器;用于存儲處理器可執(zhí)行指令的存儲器;其中,所述處理器,用于在運(yùn)行待測試的程序的過程中,對所述程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),對所述非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,根據(jù)所述第一函數(shù)調(diào)用信息和所述托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,進(jìn)而輸出所述第二函數(shù)調(diào)用信息,其中,所述非托管函數(shù)被允許直接運(yùn)行在中央處理器CPU上,所述hook操作用于監(jiān)控所述非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,所述第一函數(shù)調(diào)用信息至少包括:函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值,所述第二函數(shù)調(diào)用信息中包括具有對應(yīng)關(guān)系的所述托管函數(shù)的函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值。
在本發(fā)明實(shí)施例中,通過在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,進(jìn)而輸出得到的第二函數(shù)調(diào)用信息,通過hook操作技術(shù)來得到第一函數(shù)調(diào)用信息,再得到根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成的第二函數(shù)調(diào)用信息,從而不會出現(xiàn)crash崩潰現(xiàn)象,進(jìn)而解決了相關(guān)技術(shù)中采用mono提供的分析工具獲取托管函數(shù)的調(diào)用情況的技術(shù)方案,偶現(xiàn)crash現(xiàn)象的技術(shù)問題。
附圖說明
此處所說明的附圖用來提供對本發(fā)明的進(jìn)一步理解,構(gòu)成本申請的一部分,本發(fā)明的示意性實(shí)施例及其說明用于解釋本發(fā)明,并不構(gòu)成對本發(fā)明的不當(dāng)限定。在附圖中:
圖1是根據(jù)本發(fā)明實(shí)施例的一種可選的函數(shù)調(diào)用信息的獲取方法的應(yīng)用環(huán)境示意圖;
圖2是根據(jù)本發(fā)明實(shí)施例的一種可選的函數(shù)調(diào)用信息的獲取方法的流程圖;
圖3為根據(jù)本發(fā)明示例的編譯函數(shù)的一種流程示意圖;
圖4為根據(jù)本發(fā)明示例的編譯函數(shù)的另一種流程示意圖;
圖5為根據(jù)本發(fā)明示例的編譯函數(shù)的又一種流程示意圖;
圖6為根據(jù)本發(fā)明示例的根據(jù)函數(shù)指針fp監(jiān)聽參數(shù)和返回值的流程圖;
圖7為根據(jù)本發(fā)明示例的監(jiān)控函數(shù)調(diào)用信息的流程圖;
圖8為根據(jù)本發(fā)明實(shí)施例的一種可選的函數(shù)調(diào)用信息的獲取裝置的結(jié)構(gòu)框圖;
圖9為根據(jù)本發(fā)明實(shí)施例的一種可選的函數(shù)調(diào)用信息的獲取裝置的另一結(jié)構(gòu)框圖;
圖10為根據(jù)本發(fā)明實(shí)施例的一種可選的第一確定單元的結(jié)構(gòu)框圖;
圖11為根據(jù)本發(fā)明實(shí)施例的一種可選的測試設(shè)備的結(jié)構(gòu)框圖;
圖12為根據(jù)本發(fā)明實(shí)施例的一種可選的產(chǎn)品設(shè)備的主界面的示意圖;
圖13為根據(jù)本發(fā)明實(shí)施例的一種可選的產(chǎn)品設(shè)備的界面示意圖;
圖14為根據(jù)本發(fā)明實(shí)施例的另一種可選的產(chǎn)品設(shè)備的界面示意圖。
具體實(shí)施方式
為了使本技術(shù)領(lǐng)域的人員更好地理解本發(fā)明方案,下面將結(jié)合本發(fā)明實(shí)施例中的附圖,對本發(fā)明實(shí)施例中的技術(shù)方案進(jìn)行清楚、完整地描述,顯然,所描述的實(shí)施例僅僅是本發(fā)明一部分的實(shí)施例,而不是全部的實(shí)施例?;诒景l(fā)明中的實(shí)施例,本領(lǐng)域普通技術(shù)人員在沒有做出創(chuàng)造性勞動前提下所獲得的所有其他實(shí)施例,都應(yīng)當(dāng)屬于本發(fā)明保護(hù)的范圍。
需要說明的是,本發(fā)明的說明書和權(quán)利要求書及上述附圖中的術(shù)語“第一”、“第二”等是用于區(qū)別類似的對象,而不必用于描述特定的順序或先后次序。應(yīng)該理解這樣使用的數(shù)據(jù)在適當(dāng)情況下可以互換,以便這里描述的本發(fā)明的實(shí)施例能夠以除了在這里圖示或描述的那些以外的順序?qū)嵤?。此外,術(shù)語“包括”和“具有”以及他們的任何變形,意圖在于覆蓋不排他的包含,例如,包含了一系列步驟或單元的過程、方法、系統(tǒng)、產(chǎn)品或設(shè)備不必限于清楚地列出的那些步驟或單元,而是可包括沒有清楚地列出的或?qū)τ谶@些過程、方法、產(chǎn)品或設(shè)備固有的其它步驟或單元。
為了更好的理解本發(fā)明實(shí)施例以下提供的技術(shù)方案,本發(fā)明實(shí)施例對實(shí)施例中出現(xiàn)的技術(shù)術(shù)語進(jìn)行解釋說明。
手游:手機(jī)游戲的簡稱,相對于PC游戲而言,在手機(jī)上運(yùn)行的游戲。
Native代碼:也叫非托管代碼,指可以直接運(yùn)行在某一架構(gòu)的CPU上的指令序列,也可以指代那些可有直接編譯成這類指令序列的高級語言,比如C/C++語言,但是像依賴虛擬機(jī)運(yùn)行的java和依賴.Net庫運(yùn)行的就不能理解為是非托管代碼。
.Net框架:由微軟開發(fā)的一種采用虛擬機(jī)運(yùn)行的變成平臺,以通用語言運(yùn)行庫為基礎(chǔ),支持多種語言(C#,F#,VB.NET,C++,Python等)的開發(fā)。
托管代碼:相對于Native代碼的概念,指的是它在運(yùn)行時代碼是被托管到某一個框架上執(zhí)行的,在本發(fā)明實(shí)施例中,托管代碼可以理解為在.Net框架上運(yùn)行的代碼,本發(fā)明實(shí)施例中的托管框架至少包括Mono運(yùn)行庫。
Mono運(yùn)行庫:一個開源的,且可以運(yùn)行在.Net程序的托管框架。
Hook技術(shù):指可以監(jiān)控某一個Native代碼的函數(shù)運(yùn)行時的參數(shù)和返回值的技術(shù)。
實(shí)施例1
根據(jù)本發(fā)明實(shí)施例,提供了一種函數(shù)調(diào)用情況的獲取方法的實(shí)施例。作為一種可選的實(shí)施例,該函數(shù)調(diào)用情況的獲取方法可以但不限于應(yīng)用于如圖1所示的應(yīng)用環(huán)境中。測試設(shè)備102在終端100運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),然后對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,進(jìn)而輸出得到的第二函數(shù)調(diào)用信息,其中,非托管函數(shù)被允許直接運(yùn)行在中央處理器CPU上,hook操作用于監(jiān)控非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,第一函數(shù)調(diào)用信息至少包括:函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值,第二函數(shù)調(diào)用信息中包括具有對應(yīng)關(guān)系的托管函數(shù)的函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值。
在上述函數(shù)調(diào)用信息的獲取方法中,通過在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,進(jìn)而輸出得到的第二函數(shù)調(diào)用信息,通過hook操作技術(shù)來得到第一函數(shù)調(diào)用信息,再得到根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成的第二函數(shù)調(diào)用信息,從而不會出現(xiàn)crash崩潰現(xiàn)象,進(jìn)而解決了相關(guān)技術(shù)中采用mono提供的分析工具獲取托管函數(shù)的調(diào)用情況的技術(shù)方案,偶現(xiàn)crash現(xiàn)象的技術(shù)問題。
可選地,在本實(shí)施例中,上述終端可以包括但不限于以下至少之一:手機(jī)、平板電腦、筆記本電腦、臺式PC機(jī)及其他用于播放視頻的終端。
根據(jù)本發(fā)明實(shí)施例,提供了一種函數(shù)調(diào)用信息的獲取方法,如圖2所示,該方法包括以下步驟:
步驟S202,在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),其中,非托管函數(shù)被允許直接運(yùn)行在中央處理器CPU上;
步驟S204,對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,其中,hook操作用于監(jiān)控非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,第一函數(shù)調(diào)用信息至少包括:函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;
步驟S206,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,其中,第二函數(shù)調(diào)用信息中包括具有對應(yīng)關(guān)系的托管函數(shù)的函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;
步驟S208,輸出第二函數(shù)調(diào)用信息。
可選地,在本實(shí)施例中,上述函數(shù)調(diào)用情況的獲取方法可以但不限于應(yīng)用于測試設(shè)備中,也可以應(yīng)用于終端中,本發(fā)明實(shí)施例對此不作任何限定。需要說明的是,本發(fā)明實(shí)施例對第一函數(shù)調(diào)用信息和第二函數(shù)調(diào)用信息不作具體限定,例如,第一函數(shù)調(diào)用信息還可以包括函數(shù)名和發(fā)生的行為,其中,發(fā)生的行為可以是進(jìn)入函數(shù),也可以是退出函數(shù);第二函數(shù)調(diào)用信息中還可以包括發(fā)生的行為。
通過上述各個步驟的實(shí)現(xiàn),在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,進(jìn)而輸出得到的第二函數(shù)調(diào)用信息,通過hook操作技術(shù)來得到第一函數(shù)調(diào)用信息,再得到根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成的第二函數(shù)調(diào)用信息,從而不會出現(xiàn)crash崩潰現(xiàn)象,進(jìn)而解決了相關(guān)技術(shù)中采用mono提供的分析工具獲取托管函數(shù)的調(diào)用情況的技術(shù)方案,偶現(xiàn)crash現(xiàn)象的技術(shù)問題。
對于上述步驟S202可以有多種實(shí)現(xiàn)方式,在一個可選示例中,可以通過編譯函數(shù)對上述托管函數(shù)進(jìn)行編譯得到非托管函數(shù),本發(fā)明實(shí)施例中的編譯函數(shù)可以是函數(shù)mono_compile_method,也可以是函數(shù)mono_jit_compile_method,還可以是mono_jit_compile_method_with_opt,只要是能夠?qū)⑼泄芎瘮?shù)編譯成非托管函數(shù),均在本發(fā)明實(shí)施例的保護(hù)范圍內(nèi)。
需要說明的是,由于步驟S202是在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯進(jìn)而得到非托管函數(shù)的,也就是說,本發(fā)明實(shí)施例的技術(shù)方案能夠獲取到運(yùn)行時托管函數(shù)的調(diào)用信息,解決了相關(guān)技術(shù)中無法記錄運(yùn)行時托管函數(shù)的調(diào)用信息的問題。
可選地,在對非托管函數(shù)進(jìn)行鉤子hook操作之后,且在根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息之前,本發(fā)明實(shí)施例還提供了以下技術(shù)方案:根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與非托管函數(shù)的第一函數(shù)指針對應(yīng)的托管函數(shù)的第二函數(shù)指針;通過第二函數(shù)指針查找到托管函數(shù)的函數(shù)名。
也就是說,對非托管函數(shù)進(jìn)行hook操作之后,本發(fā)明實(shí)施例能夠獲取到非托管函數(shù)的第一函數(shù)指針,進(jìn)而根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與第一函數(shù)指針對應(yīng)的托管函數(shù)的第二函數(shù)指針,在這之前,可以建立非托管函數(shù)的第一函數(shù)指針與托管函數(shù)的第二函數(shù)指針之間的對應(yīng)關(guān)系,其中,進(jìn)行編譯所需的參數(shù)包括托管函數(shù)的第二函數(shù)指針,進(jìn)行編譯之后所得到的返回值包括非托管函數(shù)的第一函數(shù)指針,具體地,第一函數(shù)指針和第二函數(shù)指針可以通過以下方式體現(xiàn)對應(yīng)關(guān)系:第二函數(shù)指針作為上述編譯函數(shù)的參數(shù)值,第一函數(shù)指針作為將第二函數(shù)指針作為參數(shù)值代入到上述編譯函數(shù)中得到的返回值。
基于上述方案,在對非托管函數(shù)進(jìn)行鉤子hook操作之后,且在根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與非托管函數(shù)的第一函數(shù)指針對應(yīng)的托管函數(shù)的第二函數(shù)指針之前,本發(fā)明實(shí)施例還提供了以下技術(shù)方案:
通過執(zhí)行hook操作得到的返回地址調(diào)用非托管函數(shù)的匯編代碼;根據(jù)匯編代碼獲取非托管函數(shù)的第一函數(shù)指針,由于hook操作的核心思想在于替代部分代碼的執(zhí)行,本發(fā)明實(shí)施例的技術(shù)方案實(shí)際上可以理解為對非托管函數(shù)執(zhí)行完hook操作之后,能夠動態(tài)定位到被代替執(zhí)行的代碼處,上述返回地址可以用于指示被替代執(zhí)行的代碼,對于根據(jù)匯編代碼得到上述第一函數(shù)指針的技術(shù)方案,本發(fā)明實(shí)施例可以通過預(yù)先定義的hook函數(shù)實(shí)現(xiàn),也可以通過本領(lǐng)域技術(shù)人員有能力知曉的其他任何技術(shù)方案,本發(fā)明實(shí)施例對此不作限定。
可選地,本發(fā)明實(shí)施例還可以通過以下技術(shù)方案實(shí)現(xiàn)上述步驟S204的過程,例如,使用預(yù)先定義的hook函數(shù)對非托管函數(shù)進(jìn)行hook操作,其中,預(yù)先定義的hook函數(shù)輸入?yún)?shù)包括:需要被hook操作的參數(shù),預(yù)先定義的hook函數(shù)輸出參數(shù)包括:托管函數(shù)運(yùn)行時的參數(shù)和返回值,預(yù)先定義的hook函數(shù),用于監(jiān)控非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,需要說明的是,上述第一函數(shù)指針可以理解為是需要被hook操作的參數(shù)。
在實(shí)際應(yīng)用中,相關(guān)技術(shù)中的技術(shù)方案雖然能夠記錄托管函數(shù)的調(diào)用情況,但也只能調(diào)用mono主用調(diào)用托管函數(shù)而不能記錄到所有托管代碼函數(shù),本發(fā)明實(shí)施例在執(zhí)行對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯時,通過對所有待調(diào)用的托管函數(shù)進(jìn)行編譯,進(jìn)而能夠獲取到所有托管函數(shù)的調(diào)用信息。
以下結(jié)合一具體示例對上述函數(shù)調(diào)用信息的獲取過程進(jìn)行解釋說明,但不用于限定本發(fā)明實(shí)施例。
本發(fā)明示例的主要思想在于通過編譯函數(shù)對托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),進(jìn)而對編譯過的非托管函數(shù)進(jìn)行hook操作攔截來實(shí)現(xiàn)監(jiān)控運(yùn)行時的參數(shù)和返回值的功能,即通過hook操作實(shí)現(xiàn)獲取函數(shù)調(diào)用信息。
步驟S1,通過編譯函數(shù)對托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),進(jìn)而hook操作得到非托管函數(shù)的函數(shù)指針fp(相當(dāng)于上述實(shí)施例的第一函數(shù)指針);
基于上述分析可知,編譯函數(shù)可以是函數(shù)mono_compile_method,也可以是函數(shù)mono_jit_compile_method,還可以是函數(shù)mono_jit_compile_method_with_opt,對于不同的編譯函數(shù)得到非托管函數(shù)的函數(shù)指針fp的流程如下所示:
圖3為根據(jù)本發(fā)明示例的編譯函數(shù)的一種流程示意圖,如圖3所示,當(dāng)編譯函數(shù)為函數(shù)mono_compile_method時,函數(shù)mono_compile_method完成的功能通過以下步驟體現(xiàn):
步驟S302,獲取托管函數(shù)的指針mt(相當(dāng)于上述實(shí)施例的第二函數(shù)指針);
步驟S304,將指針mt作為參數(shù)值代入到函數(shù)mono_compile_method中,得到函數(shù)指針fp;
步驟S306,通過hook操作得到非托管函數(shù)(也可以叫native函數(shù))的函數(shù)指針fp。
圖4為根據(jù)本發(fā)明示例的編譯函數(shù)的另一種流程示意圖,如圖4所示,當(dāng)編譯函數(shù)為函數(shù)mono_jit_compile_method時,函數(shù)mono_jit_compile_method完成的功能通過以下步驟體現(xiàn):
步驟S402,獲取托管函數(shù)的指針mt(相當(dāng)于上述實(shí)施例的第二函數(shù)指針);
步驟S404,將指針mt作為參數(shù)值代入到函數(shù)mono_jit_compile_method中,得到函數(shù)指針fp;
步驟S406,通過hook操作得到非托管函數(shù)(也可以叫native函數(shù))的函數(shù)指針fp。
圖5為根據(jù)本發(fā)明示例的編譯函數(shù)的又一種流程示意圖,如圖5所示,當(dāng)編譯函數(shù)為函數(shù)mono_jit_compile_method_with_opt時,函數(shù)mono_jit_compile_method_with_opt完成的功能通過以下步驟體現(xiàn):
步驟S502,獲取托管函數(shù)的指針mt(相當(dāng)于上述實(shí)施例的第二函數(shù)指針);
步驟S504,將指針mt作為參數(shù)值代入到函數(shù)mono_jit_compile_method_with_opt中,得到函數(shù)指針fp;
步驟S506,通過hook操作得到非托管函數(shù)(也可以叫native函數(shù))的函數(shù)指針fp。
進(jìn)一步地,在本發(fā)明示例中,由于所有的托管函數(shù)都需要翻譯成非托管函數(shù),也就是說,在正在運(yùn)行的托管程序中,所有的托管函數(shù)都會調(diào)用上述列舉的多個編譯函數(shù)進(jìn)行編譯,進(jìn)而能夠?qū)崿F(xiàn)對所有的托管函數(shù)都能夠獲取到函數(shù)調(diào)用信息,進(jìn)而通過監(jiān)聽函數(shù)指針fp的參數(shù)和返回值,就能夠起到監(jiān)控所有托管函數(shù)。
圖6為根據(jù)本發(fā)明示例的根據(jù)函數(shù)指針fp監(jiān)聽參數(shù)和返回值的流程圖,如圖6所示,主要包括以下步驟:
步驟S602,通過編譯函數(shù)mono_compile_method獲取到非托管函數(shù)中的函數(shù)指針fp;
步驟S604,通過hook操作得到上述函數(shù)指針fp;
步驟S606,通過預(yù)先定義的hook函數(shù)監(jiān)聽函數(shù)指針fp的參數(shù)和返回值。
在上述技術(shù)方案的基礎(chǔ)上,可以定義一個字典記錄MonoMethod的指針mt和mt編譯成native代碼后的函數(shù)指針fp的對應(yīng)關(guān)系:map<mt,fp>,當(dāng)執(zhí)行被hook的函數(shù)fp中后會被hook到預(yù)先定義的hook函數(shù)中執(zhí)行,在預(yù)先定義的hook函數(shù)中通過返回地址回溯到調(diào)用者調(diào)用fp的匯編代碼,根據(jù)這條匯編代碼參考ARM指令集可以計算出fp的值,然后遍歷mt和fp對應(yīng)的字典記錄就可以確定本次調(diào)用的函數(shù)的MonoMethod指針mt,調(diào)用mono_method_get_name可以得到本次調(diào)用的函數(shù)的完整函數(shù)名,再在自定義hook函數(shù)中記錄下函數(shù)的函數(shù)進(jìn)入時間、函數(shù)退出時間、函數(shù)參數(shù)和函數(shù)返回值就可以完成對托管代碼的函數(shù)監(jiān)控功能,監(jiān)控的數(shù)據(jù)至少包括:函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間、函數(shù)參數(shù)和函數(shù)返回值,具體地,經(jīng)過編譯函數(shù)編譯成非托管函數(shù)之后,獲取到非托管函數(shù)的函數(shù)指針fp,對獲取到的fp執(zhí)行hook操作,其中,這個fp就可以理解為是“被hook函數(shù)”,上述實(shí)施例中預(yù)先定義的hook函數(shù)可以存在有多種情況,預(yù)先定義的hook函數(shù)主要用于知曉預(yù)先定義的hook函數(shù)自身被調(diào)用時,是代替哪個函數(shù)去執(zhí)行的,所以預(yù)先定義的hook函數(shù)動態(tài)定位到被替代的函數(shù)fp,這個過程可以大致理解為是通過返回地址回溯到fp值的過程。
具體流程見圖7,圖7為根據(jù)本發(fā)明示例的監(jiān)控函數(shù)調(diào)用信息的流程圖,如圖7所示,主要包括以下步驟:
步驟S702,當(dāng)前正在運(yùn)行的程序中執(zhí)行一次非托管函數(shù),以及定義mt與fp的對應(yīng)關(guān)系:map<mt,fp>;
步驟S704,通過hook操作得到函數(shù)指針fp;
步驟S706,將函數(shù)指針代入到預(yù)先定義的hook函數(shù)中;
需要說明的是,通過步驟S706中代入到預(yù)先定義的hook函數(shù)中中,可以實(shí)現(xiàn)修改參數(shù)和返回值,進(jìn)而在步驟S712中就可以記錄。
步驟S708,通過返回地址(可以理解為是一種返回值)回溯到fp的值并通過查詢對應(yīng)關(guān)系map<mt,fp>得到指針mt;
步驟S710,調(diào)用mono_method_get_name可以得到本次調(diào)用的函數(shù)的完整函數(shù)名;
步驟S712,至少記錄本地調(diào)用的函數(shù)的函數(shù)進(jìn)入時間、函數(shù)退出時間,以及參數(shù)返回值。
以下從另一個角度理解上述圖7所示的技術(shù)方案,由于事先已經(jīng)hook了mono_compile_method,這個函數(shù)在游戲運(yùn)行過程中只要執(zhí)行了以此沒有編譯過的C語言,就會調(diào)用一次,調(diào)用之后將托管函數(shù)編譯成非托管函數(shù),即本發(fā)明實(shí)施例的主要思想是被動觸發(fā)執(zhí)行,主要游戲執(zhí)行了一次mono_compile_method,由于這個函數(shù)被hook替換成了my_mono_compile_method,進(jìn)而就會執(zhí)行my_mono_compile_method,而這個函數(shù)用于調(diào)用函數(shù)mono_compile_method,進(jìn)而將托管函數(shù)編譯成非托管函數(shù),mono_compile_method的其中一個參數(shù)可以理解為是上述實(shí)施例中的指針mt,其返回值就是上述函數(shù)指針fp,之后,將每次經(jīng)由my_mono_compile_method的所有方法都hook操作一遍,這樣就可以監(jiān)控所有托管函數(shù)的執(zhí)行了。
綜上,本發(fā)明實(shí)施例以及示例的技術(shù)方案能夠?qū)崟r記錄在mono中運(yùn)行的.Net程序的托管函數(shù)級別的調(diào)用以及運(yùn)行情況,可以有序地記錄函數(shù)的進(jìn)入時間,退出時間,函數(shù)的參數(shù)和返回值,最終得到的數(shù)據(jù)可以詳細(xì)地展示.Net程序在運(yùn)行時函數(shù)間的調(diào)用情況,這個過程可以根據(jù)時間需求修改參數(shù)和返回值以達(dá)到特殊的調(diào)試目的。根據(jù)記錄下的函數(shù)進(jìn)入時間和函數(shù)退出時間,還可以用來分析運(yùn)行時程序的性能,可用定位程序的性能瓶頸進(jìn)而可以進(jìn)行針對性的優(yōu)化,從而可以快速解決程序在邏輯上的性能問題,利用本發(fā)明還可以用來統(tǒng)計代碼執(zhí)行的覆蓋度,在測試中可以用來統(tǒng)計代碼執(zhí)行的覆蓋度,對試用例的代碼覆蓋情況有一個直觀的反映。
而應(yīng)用相關(guān)技術(shù)提供的技術(shù)方案,需要定位性能問題需要憑開發(fā)者的經(jīng)驗(yàn)判斷可能存在性能瓶頸的函數(shù)打log進(jìn)行判斷這些函數(shù)是否真的存在性能問題,非常耗時耗精力;此外,測試人員往往會因?yàn)椴恢雷约壕帉懙臏y試用例覆蓋了多少代碼邏輯而可能會漏測不少邏輯導(dǎo)致發(fā)布的程序有bug。
而采用本發(fā)明實(shí)施例提供的上述技術(shù)方案,不僅解決了偶現(xiàn)Crash的問題,還能記錄和修改所有托管函數(shù)運(yùn)行時的參數(shù)和返回值,利用函數(shù)的進(jìn)入和退出時間可以快速定位程序函數(shù)級別的邏輯性能瓶頸,統(tǒng)計函數(shù)的調(diào)用次數(shù)可以有針對性地對頻繁調(diào)用的函數(shù)進(jìn)行針對性的優(yōu)化,利用監(jiān)控的參數(shù)情況,可以針對性地對參數(shù)進(jìn)行優(yōu)化,通過這些數(shù)據(jù)可以提供程序的性能;測試人員還可以在黑盒測試層面獲取測試用例執(zhí)行時的代碼覆蓋率,對設(shè)計更全面的測試用例有非常大的幫助,使用修改參數(shù)和返回值的功能,可以對程序進(jìn)行邏輯層面的安全性和程序健壯性進(jìn)行針對性地測試,可以極大地方便測試工作。
需要說明的是,對于前述的各方法實(shí)施例,為了簡單描述,故將其都表述為一系列的動作組合,但是本領(lǐng)域技術(shù)人員應(yīng)該知悉,本發(fā)明并不受所描述的動作順序的限制,因?yàn)橐罁?jù)本發(fā)明,某些步驟可以采用其他順序或者同時進(jìn)行。其次,本領(lǐng)域技術(shù)人員也應(yīng)該知悉,說明書中所描述的實(shí)施例均屬于優(yōu)選實(shí)施例,所涉及的動作和模塊并不一定是本發(fā)明所必須的。
通過以上的實(shí)施方式的描述,本領(lǐng)域的技術(shù)人員可以清楚地了解到根據(jù)上述實(shí)施例的方法可借助軟件加必需的通用硬件平臺的方式來實(shí)現(xiàn),當(dāng)然也可以通過硬件,但很多情況下前者是更佳的實(shí)施方式?;谶@樣的理解,本發(fā)明的技術(shù)方案本質(zhì)上或者說對現(xiàn)有技術(shù)做出貢獻(xiàn)的部分可以以軟件產(chǎn)品的形式體現(xiàn)出來,該計算機(jī)軟件產(chǎn)品存儲在一個存儲介質(zhì)(如ROM/RAM、磁碟、光盤)中,包括若干指令用以使得一臺終端設(shè)備(可以是手機(jī),計算機(jī),服務(wù)器,或者網(wǎng)絡(luò)設(shè)備等)執(zhí)行本發(fā)明各個實(shí)施例所述的方法。
實(shí)施例2
根據(jù)本發(fā)明實(shí)施例,還提供了一種用于實(shí)施上述函數(shù)調(diào)用信息的獲取方法的函數(shù)調(diào)用信息的獲取裝置,如圖8所示,該裝置包括:
1)編譯單元80,用于在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯;
2)第一確定單元82,用于對托管函數(shù)編譯后得到非托管函數(shù),其中,非托管函數(shù)被允許直接運(yùn)行在中央處理器CPU上;
3)第二確定單元84,用于對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,其中,hook操作用于監(jiān)控非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,第一函數(shù)調(diào)用信息至少包括:函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;
4)生成單元86,用于根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,其中,第二函數(shù)調(diào)用信息中包括具有對應(yīng)關(guān)系的托管函數(shù)的函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;
5)輸出單元88,用于輸出第二函數(shù)調(diào)用信息。
可選地,在本實(shí)施例中,上述函數(shù)調(diào)用情況的獲取方法可以但不限于應(yīng)用于測試設(shè)備中,也可以應(yīng)用于終端中,本發(fā)明實(shí)施例對此不作任何限定。需要說明的是,本發(fā)明實(shí)施例對第一函數(shù)調(diào)用信息和第二函數(shù)調(diào)用信息不作具體限定,例如,第一函數(shù)調(diào)用信息還可以包括函數(shù)名和發(fā)生的行為,其中,發(fā)生的行為可以是進(jìn)入函數(shù),也可以是退出函數(shù);第二函數(shù)調(diào)用信息中還可以包括發(fā)生的行為。
需要說明的是,在本發(fā)明實(shí)施例中,在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,進(jìn)而輸出得到的第二函數(shù)調(diào)用信息,通過hook操作技術(shù)來得到第一函數(shù)調(diào)用信息,再得到根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成的第二函數(shù)調(diào)用信息,從而不會出現(xiàn)crash崩潰現(xiàn)象,進(jìn)而解決了相關(guān)技術(shù)中采用mono提供的分析工具獲取托管函數(shù)的調(diào)用情況的技術(shù)方案,偶現(xiàn)crash現(xiàn)象的技術(shù)問題。
在一個可選示例中,可以通過編譯函數(shù)對上述托管函數(shù)進(jìn)行編譯得到非托管函數(shù),本發(fā)明實(shí)施例中的編譯函數(shù)可以是函數(shù)mono_compile_method,也可以是函數(shù)mono_jit_compile_method,還可以是mono_jit_compile_method_with_opt,只要是能夠?qū)⑼泄芎瘮?shù)編譯成非托管函數(shù),均在本發(fā)明實(shí)施例的保護(hù)范圍內(nèi)。
需要說明的是,由于本發(fā)明實(shí)施例是在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯進(jìn)而得到非托管函數(shù)的,也就是說,本發(fā)明實(shí)施例的技術(shù)方案能夠獲取到運(yùn)行時托管函數(shù)的調(diào)用信息,解決了相關(guān)技術(shù)中無法記錄運(yùn)行時托管函數(shù)的調(diào)用信息的問題。
圖9為根據(jù)本發(fā)明實(shí)施例的一種可選的函數(shù)調(diào)用信息的獲取裝置的另一結(jié)構(gòu)框圖,如圖9所示,上述裝置還包括:
第一獲取單元90,用于根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與非托管函數(shù)的第一函數(shù)指針對應(yīng)的托管函數(shù)的第二函數(shù)指針;查找單元92,用于通過第二函數(shù)指針查找到托管函數(shù)的函數(shù)名。
也就是說,對非托管函數(shù)進(jìn)行hook操作之后,本發(fā)明實(shí)施例能夠獲取到非托管函數(shù)的第一函數(shù)指針,進(jìn)而根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與第一函數(shù)指針對應(yīng)的托管函數(shù)的第二函數(shù)指針,在這之前,可以建立非托管函數(shù)的第一函數(shù)指針與托管函數(shù)的第二函數(shù)指針之間的對應(yīng)關(guān)系,其中,進(jìn)行編譯所需的參數(shù)包括托管函數(shù)的第二函數(shù)指針,進(jìn)行編譯之后所得到的返回值包括非托管函數(shù)的第一函數(shù)指針,具體地,第一函數(shù)指針和第二函數(shù)指針可以通過以下方式體現(xiàn)對應(yīng)關(guān)系:第二函數(shù)指針作為上述編譯函數(shù)的參數(shù)值,第一函數(shù)指針作為將第二函數(shù)指針作為參數(shù)值代入到上述編譯函數(shù)中得到的返回值。
如圖9所示,上述裝置還包括:第二獲取單元92,用于通過執(zhí)行hook操作得到的返回地址調(diào)用非托管函數(shù)的匯編代碼;第三獲取單元94,用于根據(jù)匯編代碼獲取非托管函數(shù)的第一函數(shù)指針。
由于hook操作的核心思想在于替代部分代碼的執(zhí)行,本發(fā)明實(shí)施例的技術(shù)方案實(shí)際上可以理解為對非托管函數(shù)執(zhí)行完hook操作之后,能夠動態(tài)定位到被代替執(zhí)行的代碼處,上述返回地址可以用于指示被替代執(zhí)行的代碼,對于根據(jù)匯編代碼得到上述第一函數(shù)指針的技術(shù)方案,本發(fā)明實(shí)施例可以通過預(yù)先定義的hook函數(shù)實(shí)現(xiàn),也可以通過本領(lǐng)域技術(shù)人員有能力知曉的其他任何技術(shù)方案,本發(fā)明實(shí)施例對此不作限定。
可選地,如圖9所示,上述裝置還可以包括:
建立單元96,用于建立非托管函數(shù)的第一函數(shù)指針與托管函數(shù)的第二函數(shù)指針之間的對應(yīng)關(guān)系,其中,進(jìn)行編譯所需的參數(shù)包括托管函數(shù)的第二函數(shù)指針,進(jìn)行編譯之后所得到的返回值包括非托管函數(shù)的第一函數(shù)指針。
圖10為根據(jù)本發(fā)明實(shí)施例的一種可選的第一確定單元的結(jié)構(gòu)框圖,如圖10所示,第一確定單元82包括:
操作模塊820,用于使用預(yù)先定義的hook函數(shù)對非托管函數(shù)進(jìn)行hook操作,其中,預(yù)先定義的hook函數(shù)輸入?yún)?shù)包括:需要被hook操作的參數(shù),預(yù)先定義的hook函數(shù)輸出參數(shù)包括:托管函數(shù)運(yùn)行時的參數(shù)和返回值,預(yù)先定義的hook函數(shù),用于監(jiān)控非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,需要說明的是,上述第一函數(shù)指針可以理解為是需要被hook操作的參數(shù)。
在實(shí)際應(yīng)用中,相關(guān)技術(shù)中的技術(shù)方案雖然能夠記錄托管函數(shù)的調(diào)用情況,但也只能調(diào)用mono主用調(diào)用托管函數(shù)而不能記錄到所有托管代碼函數(shù),本發(fā)明實(shí)施例在執(zhí)行對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯時,通過編譯單元98(如圖9所示),對所有待調(diào)用的托管函數(shù)進(jìn)行編譯,進(jìn)而能夠獲取到所有托管函數(shù)的調(diào)用信息。
綜上,本發(fā)明實(shí)施例以及示例的技術(shù)方案能夠?qū)崟r記錄在mono中運(yùn)行的.Net程序的托管函數(shù)級別的調(diào)用以及運(yùn)行情況,可以有序地記錄函數(shù)的進(jìn)入時間,退出時間,函數(shù)的參數(shù)和返回值,最終得到的數(shù)據(jù)可以詳細(xì)地展示.Net程序在運(yùn)行時函數(shù)間的調(diào)用情況,這個過程可以根據(jù)時間需求修改參數(shù)和返回值以達(dá)到特殊的調(diào)試目的。根據(jù)記錄下的函數(shù)進(jìn)入時間和函數(shù)退出時間,還可以用來分析運(yùn)行時程序的性能,可用定位程序的性能瓶頸進(jìn)而可以進(jìn)行針對性的優(yōu)化,從而可以快速解決程序在邏輯上的性能問題,利用本發(fā)明還可以用來統(tǒng)計代碼執(zhí)行的覆蓋度,在測試中可以用來統(tǒng)計代碼執(zhí)行的覆蓋度,對試用例的代碼覆蓋情況有一個直觀的反映。
實(shí)施例3
根據(jù)本發(fā)明實(shí)施例,還提供了一種用于實(shí)施上述函數(shù)調(diào)用信息的獲取方法的測試設(shè)備,如圖11所示,該測試設(shè)備包括:
處理器110;
用于存儲處理器可執(zhí)行指令的存儲器112;
其中,處理器110,用于在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,進(jìn)而輸出第二函數(shù)調(diào)用信息,其中,非托管函數(shù)被允許直接運(yùn)行在中央處理器CPU上,hook操作用于監(jiān)控非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,第一函數(shù)調(diào)用信息至少包括:函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值,第二函數(shù)調(diào)用信息中包括具有對應(yīng)關(guān)系的托管函數(shù)的函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值。
可選地,測試設(shè)備還設(shè)置有操作界面,操作界面用于接收用戶操作,所述處理器,還用于根據(jù)用戶操作對與測試設(shè)備相連接的終端進(jìn)行測試得到托管代碼函數(shù)的調(diào)用信息。
處理器110,還用于將所述托管代碼函數(shù)的調(diào)用信息發(fā)送至所述終端,進(jìn)而在終端的指定文件夾下保存上述調(diào)用信息。
通過上述處理器110和存儲器112,在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,進(jìn)而輸出得到的第二函數(shù)調(diào)用信息,通過hook操作技術(shù)來得到第一函數(shù)調(diào)用信息,再得到根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成的第二函數(shù)調(diào)用信息,從而不會出現(xiàn)crash崩潰現(xiàn)象,進(jìn)而解決了相關(guān)技術(shù)中采用mono提供的分析工具獲取托管函數(shù)的調(diào)用情況的技術(shù)方案,偶現(xiàn)crash現(xiàn)象的技術(shù)問題。
對于上述步驟S202可以有多種實(shí)現(xiàn)方式,在一個可選示例中,可以通過編譯函數(shù)對上述托管函數(shù)進(jìn)行編譯得到非托管函數(shù),本發(fā)明實(shí)施例中的編譯函數(shù)可以是函數(shù)mono_compile_method,也可以是函數(shù)mono_jit_compile_method,還可以是mono_jit_compile_method_with_opt,只要是能夠?qū)⑼泄芎瘮?shù)編譯成非托管函數(shù),均在本發(fā)明實(shí)施例的保護(hù)范圍內(nèi)。
需要說明的是,由于步驟S202是在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯進(jìn)而得到非托管函數(shù)的,也就是說,本發(fā)明實(shí)施例的技術(shù)方案能夠獲取到運(yùn)行時托管函數(shù)的調(diào)用信息,解決了相關(guān)技術(shù)中無法記錄運(yùn)行時托管函數(shù)的調(diào)用信息的問題。
可選地,在對非托管函數(shù)進(jìn)行鉤子hook操作之后,且在根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息之前,本發(fā)明實(shí)施例還提供了以下技術(shù)方案:根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與非托管函數(shù)的第一函數(shù)指針對應(yīng)的托管函數(shù)的第二函數(shù)指針;通過第二函數(shù)指針查找到托管函數(shù)的函數(shù)名。
也就是說,對非托管函數(shù)進(jìn)行hook操作之后,本發(fā)明實(shí)施例能夠獲取到非托管函數(shù)的第一函數(shù)指針,進(jìn)而根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與第一函數(shù)指針對應(yīng)的托管函數(shù)的第二函數(shù)指針,在這之前,可以建立非托管函數(shù)的第一函數(shù)指針與托管函數(shù)的第二函數(shù)指針之間的對應(yīng)關(guān)系,其中,進(jìn)行編譯所需的參數(shù)包括托管函數(shù)的第二函數(shù)指針,進(jìn)行編譯之后所得到的返回值包括非托管函數(shù)的第一函數(shù)指針,具體地,第一函數(shù)指針和第二函數(shù)指針可以通過以下方式體現(xiàn)對應(yīng)關(guān)系:第二函數(shù)指針作為上述編譯函數(shù)的參數(shù)值,第一函數(shù)指針作為將第二函數(shù)指針作為參數(shù)值代入到上述編譯函數(shù)中得到的返回值。
基于上述方案,在對非托管函數(shù)進(jìn)行鉤子hook操作之后,且在根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與非托管函數(shù)的第一函數(shù)指針對應(yīng)的托管函數(shù)的第二函數(shù)指針之前,本發(fā)明實(shí)施例還提供了以下技術(shù)方案:
通過執(zhí)行hook操作得到的返回地址獲取非托管函數(shù)的匯編代碼;根據(jù)匯編代碼獲取非托管函數(shù)的第一函數(shù)指針,由于hook操作的核心思想在于替代部分代碼的執(zhí)行,本發(fā)明實(shí)施例的技術(shù)方案實(shí)際上可以理解為對非托管函數(shù)執(zhí)行完hook操作之后,能夠動態(tài)定位到被代替執(zhí)行的代碼處,上述返回地址可以用于指示被替代執(zhí)行的代碼,對于根據(jù)匯編代碼得到上述第一函數(shù)指針的技術(shù)方案,本發(fā)明實(shí)施例可以通過預(yù)先定義的hook函數(shù)實(shí)現(xiàn),也可以通過本領(lǐng)域技術(shù)人員有能力知曉的其他任何技術(shù)方案,本發(fā)明實(shí)施例對此不作限定。
可選地,本發(fā)明實(shí)施例還可以通過以下技術(shù)方案實(shí)現(xiàn)上述步驟S204的過程,使用預(yù)先定義的hook函數(shù)對非托管函數(shù)進(jìn)行hook操作,其中,預(yù)先定義的hook函數(shù)輸入?yún)?shù)包括:需要被hook操作的參數(shù),預(yù)先定義的hook函數(shù)輸出參數(shù)包括:托管函數(shù)運(yùn)行時的參數(shù)和返回值,預(yù)先定義的hook函數(shù),用于監(jiān)控非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,需要說明的是,上述第一函數(shù)指針可以理解為是需要被hook操作的參數(shù)。
在實(shí)際應(yīng)用中,相關(guān)技術(shù)中的技術(shù)方案雖然能夠記錄托管函數(shù)的調(diào)用情況,但也只能調(diào)用mono主用調(diào)用托管函數(shù)而不能記錄到所有托管代碼函數(shù),本發(fā)明實(shí)施例在執(zhí)行對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯時,通過對所有待調(diào)用的托管函數(shù)進(jìn)行編譯,進(jìn)而能夠獲取到所有托管函數(shù)的調(diào)用信息。
以下結(jié)合一示例對測試設(shè)備的獲取函數(shù)調(diào)用信息的流程以及測試設(shè)備與終端之間的流程進(jìn)行解釋說明。
上述測試設(shè)備可以對基于Mono運(yùn)行的.NET程序進(jìn)行托管代碼函數(shù)的測試,本發(fā)明示例通過展現(xiàn)一個測試設(shè)備的產(chǎn)品客戶端的顯示形式來說明測試設(shè)備對終端測試以及獲取函數(shù)調(diào)用信息的過程,。
圖12為根據(jù)本發(fā)明實(shí)施例的一種可選的產(chǎn)品設(shè)備的主界面的示意圖,如圖12所示,
打開產(chǎn)品客戶端,并與終端手機(jī)進(jìn)行了連接,本發(fā)明實(shí)施例的連接可以采用有線方式,也可以藍(lán)牙,無線網(wǎng)等無線方式,測設(shè)設(shè)備會根據(jù)實(shí)際需要選擇終端上的一個手游進(jìn)行測試,選擇完待進(jìn)行測試的游戲之后,會出現(xiàn)如圖13所示的界面。
如圖14所示,點(diǎn)擊確定選擇的待測試游戲以后,測試設(shè)備首先會對游戲進(jìn)行必要的初始化工作,初始化流程完成以后,再拉起游戲。
測試設(shè)備就會開始執(zhí)行測試過程,測試過程結(jié)束后,測試設(shè)備會將測試結(jié)果發(fā)送至終端,終端在預(yù)先設(shè)備的目錄下就會生成一個文件(可以是function.txt文件),在這個指定文件夾下,詳細(xì)記錄了游戲運(yùn)行過程中對托管代碼函數(shù)的調(diào)用情況,如下所示:
1642421[1467193517,604471204]leave:Npc 2:Update()ret:0
1642422[1467193517,604532239]enter:HitEffectController:Update()
1642423[1467193517,604593274]leave:HitEffectController:Update()ret:0.
由上述游戲運(yùn)行過程中的記錄結(jié)果可知,上述方括號內(nèi)的數(shù)據(jù)為發(fā)生這個行為的時間戳,第一個數(shù)據(jù)的單位為秒,第二個數(shù)據(jù)的單位為納秒,緊接著為發(fā)生的行為,enter表示進(jìn)入這個函數(shù),leave表示退出這個函數(shù),行為后面的即為函數(shù)名,可以看到參數(shù)和返回值。開發(fā)人員可以利用這些信息進(jìn)行統(tǒng)計以定位出程序的性能問題,測試人員可以根據(jù)這些信息在黑盒的情況下大致判斷程序的運(yùn)行邏輯,同時也可以測試用例的代碼覆蓋率。
可選地,本實(shí)施例中的具體示例可以參考上述實(shí)施例1和實(shí)施例2中所描述的示例,本實(shí)施例在此不再贅述。
實(shí)施例4
本發(fā)明的實(shí)施例還提供了一種存儲介質(zhì)。可選地,在本實(shí)施例中,上述存儲介質(zhì)可以位于測試設(shè)備中。
可選地,在本實(shí)施例中,存儲介質(zhì)被設(shè)置為存儲用于執(zhí)行以下步驟的程序代碼:
S1,在運(yùn)行待測試的程序的過程中,對程序中待調(diào)用的托管函數(shù)進(jìn)行編譯,得到非托管函數(shù),其中,非托管函數(shù)被允許直接運(yùn)行在中央處理器CPU上;
S2,對非托管函數(shù)進(jìn)行鉤子hook操作,得到第一函數(shù)調(diào)用信息,其中,hook操作用于監(jiān)控非托管函數(shù)在運(yùn)行時的參數(shù)和返回值,第一函數(shù)調(diào)用信息至少包括:函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;
S3,根據(jù)第一函數(shù)調(diào)用信息和托管函數(shù)的函數(shù)名生成第二函數(shù)調(diào)用信息,其中,第二函數(shù)調(diào)用信息中包括具有對應(yīng)關(guān)系的托管函數(shù)的函數(shù)名、函數(shù)進(jìn)入時間、函數(shù)退出時間,函數(shù)返回值;
S4,輸出第二函數(shù)調(diào)用信息。
可選地,存儲介質(zhì)還被設(shè)置為存儲用于執(zhí)行以下步驟的程序代碼:
S1,根據(jù)預(yù)先建立的對應(yīng)關(guān)系獲取與所述非托管函數(shù)的第一函數(shù)指針對應(yīng)的所述托管函數(shù)的第二函數(shù)指針;
S2,通過所述第二函數(shù)指針查找到所述托管函數(shù)的所述函數(shù)名。
可選地,存儲介質(zhì)還被設(shè)置為存儲用于執(zhí)行以下步驟的程序代碼:
S1,通過執(zhí)行所述hook操作得到的返回地址獲取所述非托管函數(shù)的匯編代碼;
S2,根據(jù)所述匯編代碼獲取所述非托管函數(shù)的第一函數(shù)指針。
可選地,存儲介質(zhì)還被設(shè)置為存儲用于執(zhí)行以下步驟的程序代碼:
S1,建立所述非托管函數(shù)的第一函數(shù)指針與所述托管函數(shù)的第二函數(shù)指針之間的所述對應(yīng)關(guān)系,其中,進(jìn)行所述編譯所需的參數(shù)包括所述托管函數(shù)的第二函數(shù)指針,進(jìn)行所述編譯之后所得到的返回值包括所述非托管函數(shù)的第一函數(shù)指針。
可選地,存儲介質(zhì)還被設(shè)置為存儲用于執(zhí)行以下步驟的程序代碼:
S1,使用預(yù)先定義的hook函數(shù)對非托管函數(shù)進(jìn)行所述hook操作,其中,所述預(yù)先定義的hook函數(shù)輸入?yún)?shù)包括:需要被hook操作的參數(shù),所述預(yù)先定義的hook函數(shù)輸出參數(shù)包括:所述托管函數(shù)運(yùn)行時的參數(shù)和返回值,所述預(yù)先定義的hook函數(shù),用于監(jiān)控所述非托管函數(shù)在運(yùn)行時的參數(shù)和返回值。
可選地,存儲介質(zhì)還被設(shè)置為存儲用于執(zhí)行以下步驟的程序代碼:
S1,對所述程序中所有待調(diào)用的托管函數(shù)進(jìn)行編譯,得到對應(yīng)的非托管函數(shù)。
可選地,在本實(shí)施例中,上述存儲介質(zhì)可以包括但不限于:U盤、只讀存儲器(ROM,Read-Only Memory)、隨機(jī)存取存儲器(RAM,Random Access Memory)、移動硬盤、磁碟或者光盤等各種可以存儲程序代碼的介質(zhì)。
可選地,本實(shí)施例中的具體示例可以參考上述實(shí)施例1和實(shí)施例2中所描述的示例,本實(shí)施例在此不再贅述。
綜上所述,本發(fā)明實(shí)施例達(dá)到了以下技術(shù)效果:能夠?qū)崟r記錄在mono中運(yùn)行的.Net程序的托管函數(shù)級別的調(diào)用以及運(yùn)行情況,可以有序地記錄函數(shù)的進(jìn)入時間,退出時間,函數(shù)的參數(shù)和返回值,最終得到的數(shù)據(jù)可以詳細(xì)地展示.Net程序在運(yùn)行時函數(shù)間的調(diào)用情況,這個過程可以根據(jù)時間需求修改參數(shù)和返回值以達(dá)到特殊的調(diào)試目的。根據(jù)記錄下的函數(shù)進(jìn)入時間和函數(shù)退出時間,還可以用來分析運(yùn)行時程序的性能,可用定位程序的性能瓶頸進(jìn)而可以進(jìn)行針對性的優(yōu)化,從而可以快速解決程序在邏輯上的性能問題,利用本發(fā)明還可以用來統(tǒng)計代碼執(zhí)行的覆蓋度,在測試中可以用來統(tǒng)計代碼執(zhí)行的覆蓋度,對試用例的代碼覆蓋情況有一個直觀的反映。
上述本發(fā)明實(shí)施例序號僅僅為了描述,不代表實(shí)施例的優(yōu)劣。
上述實(shí)施例中的集成的單元如果以軟件功能單元的形式實(shí)現(xiàn)并作為獨(dú)立的產(chǎn)品銷售或使用時,可以存儲在上述計算機(jī)可讀取的存儲介質(zhì)中。基于這樣的理解,本發(fā)明的技術(shù)方案本質(zhì)上或者說對現(xiàn)有技術(shù)做出貢獻(xiàn)的部分或者該技術(shù)方案的全部或部分可以以軟件產(chǎn)品的形式體現(xiàn)出來,該計算機(jī)軟件產(chǎn)品存儲在存儲介質(zhì)中,包括若干指令用以使得一臺或多臺計算機(jī)設(shè)備(可為個人計算機(jī)、服務(wù)器或者網(wǎng)絡(luò)設(shè)備等)執(zhí)行本發(fā)明各個實(shí)施例所述方法的全部或部分步驟。
在本發(fā)明的上述實(shí)施例中,對各個實(shí)施例的描述都各有側(cè)重,某個實(shí)施例中沒有詳述的部分,可以參見其他實(shí)施例的相關(guān)描述。
在本申請所提供的幾個實(shí)施例中,應(yīng)該理解到,所揭露的客戶端,可通過其它的方式實(shí)現(xiàn)。其中,以上所描述的裝置實(shí)施例僅僅是示意性的,例如所述單元的劃分,僅僅為一種邏輯功能劃分,實(shí)際實(shí)現(xiàn)時可以有另外的劃分方式,例如多個單元或組件可以結(jié)合或者可以集成到另一個系統(tǒng),或一些特征可以忽略,或不執(zhí)行。另一點(diǎn),所顯示或討論的相互之間的耦合或直接耦合或通信連接可以是通過一些接口,單元或模塊的間接耦合或通信連接,可以是電性或其它的形式。
所述作為分離部件說明的單元可以是或者也可以不是物理上分開的,作為單元顯示的部件可以是或者也可以不是物理單元,即可以位于一個地方,或者也可以分布到多個網(wǎng)絡(luò)單元上??梢愿鶕?jù)實(shí)際的需要選擇其中的部分或者全部單元來實(shí)現(xiàn)本實(shí)施例方案的目的。
另外,在本發(fā)明各個實(shí)施例中的各功能單元可以集成在一個處理單元中,也可以是各個單元單獨(dú)物理存在,也可以兩個或兩個以上單元集成在一個單元中。上述集成的單元既可以采用硬件的形式實(shí)現(xiàn),也可以采用軟件功能單元的形式實(shí)現(xiàn)。
以上所述僅是本發(fā)明的優(yōu)選實(shí)施方式,應(yīng)當(dāng)指出,對于本技術(shù)領(lǐng)域的普通技術(shù)人員來說,在不脫離本發(fā)明原理的前提下,還可以做出若干改進(jìn)和潤飾,這些改進(jìn)和潤飾也應(yīng)視為本發(fā)明的保護(hù)范圍。