專利名稱:用于分析運行時存儲器訪問錯誤的方法和系統(tǒng)的制作方法
技術(shù)領(lǐng)域:
本發(fā)明涉及軟件開發(fā),并且更具體地,涉及計算機程序的運行時存儲器分析。
背景技術(shù):
許多現(xiàn)代程序設(shè)計語言不支持防止運行時存儲器訪問錯誤的程序設(shè)計結(jié)構(gòu)。運行時存儲器訪問錯誤可以包括、但不限于從未初始化的存儲器讀取或?qū)懭?、超出所定義的數(shù)組的范圍讀取或?qū)懭?、存儲器泄漏、空閑存儲器訪問等。不支持防止這樣的動作的構(gòu)造的現(xiàn)代程序設(shè)計語言的一個例子是C或C++程序設(shè)計語言。當(dāng)編譯以C或C++編寫的程序時,通常未檢測到諸如以上所指出的運行時存儲器訪問錯誤。
舉例來說,在C/C++內(nèi),開發(fā)者可能定義特定大小的數(shù)組并且然后訪問超過該數(shù)組大小的元素??紤]圖1中所示的代碼實例。如所示出的,對a[21]的訪問針對的不是由程序所分配的存儲器部分,并且因此可能是堆(heap)上未分配的存儲器或者是由另一段程序所分配的存儲器。這樣的動作是非法的,但卻通常未被常規(guī)的C/C++編譯器檢測到。
然而,一些運行時分析工具,例如那些利用目標代碼插入(OCI)技術(shù)的工具,可以檢測這些類別的錯誤。OCI是在計算機程序的目標文件內(nèi)插入校驗指令的技術(shù)。具有這種插入其中的校驗指令的程序被稱作插裝程序(instrumented program)。校驗指令實現(xiàn)各種有關(guān)存儲器使用的監(jiān)控和/或跟蹤功能??梢栽谠L問(reference)存儲器的程序指令之間插入校驗指令,即監(jiān)控讀取和寫入操作以及存儲器分配和解除分配。
擴展與運行時存儲器訪問錯誤的檢測有關(guān)的運行時分析工具的功能會是有益的。
發(fā)明內(nèi)容
本文所公開的實施例提供了與計算機程序的運行時存儲器分析有關(guān)的方法和制品(article of manufacture)。本發(fā)明的一個實施例可以包括分析計算機程序中運行時存儲器訪問錯誤方法。所述方法可以包括利用運行時分析代碼插裝(instrument)計算機程序并且檢測已插裝的計算機程序的運行時存儲器訪問錯誤。響應(yīng)于檢測運行時存儲器訪問錯誤,所述方法還可以包括動態(tài)地設(shè)置監(jiān)測點。
本發(fā)明的另一實施例可以包括分析計算機程序中運行時存儲器訪問錯誤的方法,所述方法包括檢測所述計算機程序中的運行時存儲器訪問錯誤、為運行時存儲器訪問錯誤確定上下文信息,并且將上下文信息與用戶規(guī)定的屬性進行比較。如果上下文信息與用戶指定的屬性匹配,則可以為所述計算機程序自動地設(shè)置監(jiān)測點。
而本發(fā)明的另一實施例可以包括機器可讀存儲器,所述機器可讀存儲器上具有存儲于其上的多個使得該機器執(zhí)行本文所公開的各種步驟和/或功能的代碼區(qū)段。
附圖中示出了目前優(yōu)選的實施例;然而,應(yīng)當(dāng)理解到本發(fā)明不限于所示出的明確的裝置和手段。
圖1描述了對理解本文所公開的實施例有用的示范性源代碼。
圖2是對理解本文所公開的實施例有用的示范性源代碼。
圖3是關(guān)于根據(jù)圖2所描述的錯誤由運行時分析工具所產(chǎn)生的示例輸出。
圖4是描述依照本發(fā)明的一個實施例的運行時存儲器分析方法的流程圖。
具體實施例方式
盡管本說明書以規(guī)定了被認為是新穎的本發(fā)明的特征的權(quán)利要求作為結(jié)論,但是可以認為考慮根據(jù)結(jié)合附圖的描述將更好地理解本發(fā)明。如所需的,本文公開了本發(fā)明的具體實施例;然而,應(yīng)當(dāng)認識到,所公開的實施例僅是本發(fā)明的示范,其可以以各種形式實施。因此,不認為本文所公開的特定結(jié)構(gòu)的和功能的細節(jié)是限制,而僅認為是用于權(quán)利要求的基本原理以及用于教導(dǎo)本領(lǐng)域的技術(shù)人員以實際上任何適當(dāng)?shù)木唧w結(jié)構(gòu)來多樣地使用本發(fā)明裝置的代表性基本原理。此外,本文所使用的術(shù)語和慣用語并不打算限制而僅是提供本發(fā)明的可理解的描述。
本文所公開的實施例提供了用于在計算機程序中動態(tài)地設(shè)置監(jiān)測點的技術(shù)。依照本文所公開的發(fā)明裝置,用戶或開發(fā)者可以設(shè)立各種條件。如果條件滿足,就可以動態(tài)地創(chuàng)建監(jiān)測點。此外,當(dāng)滿足設(shè)立的條件并且創(chuàng)建了監(jiān)測點時就可以自動地執(zhí)行一個或多個程序動作。
使用軟件分析工具可以實現(xiàn)本文所描述的各種功能。例如,在一個實施例中,可以將本文所描述的各種功能實現(xiàn)為Rational PurifyPlus系列軟件分析工具的一個或多個成員的擴展,其中來自紐約阿蒙克(Armonk)的國際商業(yè)機器公司(IBM)的Rational PurifyPlus系列軟件分析工具是商業(yè)上可用的。PurifyPlus是為軟件開發(fā)者和測試者提供運行時分析功能的計算機程序系列。一般而言,運行時分析指的是使用在執(zhí)行處于測試中的程序期間所收集的數(shù)據(jù)來理解應(yīng)用行為的實踐。使用PurifyPlus可以分析的各種開發(fā)活動可以包括、但不限于本機C/C++應(yīng)用中的存儲器損壞檢測和存儲器剖析(memory profiling)、Java和.NET管理代碼應(yīng)用中的存儲器剖析、識別慢的或無效的代碼部分的性能剖析、代碼覆蓋分析以及運行時跟蹤。
本文所公開的產(chǎn)品意圖提供用于教導(dǎo)本領(lǐng)域的技術(shù)人員更好地理解本文所公開的發(fā)明裝置的基本原理。然而,應(yīng)當(dāng)認識到,本發(fā)明可以實現(xiàn)為獨立的應(yīng)用、更大的應(yīng)用的一部分或者以實際上任何適當(dāng)?shù)木唧w結(jié)構(gòu)、計算機程序和/或其部分來實現(xiàn)。
圖2是對理解本文所公開的實施例有用的示范性源代碼。使用本文所描述的運行時分析工具來執(zhí)行圖2中所描述的程序會導(dǎo)致第10行所報告的“空閑存儲器讀”(FMR)錯誤的檢測。FMR類型的運行時存儲器訪問錯誤指的是數(shù)組在被訪問之前已經(jīng)被釋放的情形。
圖3是關(guān)于根據(jù)圖2所描述的錯誤由運行時分析工具所產(chǎn)生的示例輸出。在所提供的關(guān)于運行時存儲器訪問錯誤的上下文信息的不同項目中,該輸出指出了堆棧跟蹤信息。堆棧跟蹤信息指出使用對源于“calloc”內(nèi)的“malloc”的調(diào)用來分配存儲塊,其中從“main”調(diào)用“calloc”,而從“start”調(diào)用“main”。
依照本發(fā)明的一個實施例,該上下文信息可以用于動態(tài)地創(chuàng)建和/或設(shè)置監(jiān)測點。更具體地,該上下文信息可以與用戶規(guī)定的信息,即指令的一個或多個屬性進行比較。用戶指定的屬性指出動態(tài)地創(chuàng)建監(jiān)測點的環(huán)境。如果上下文信息與用戶指定的屬性匹配,那么可以自動地設(shè)置監(jiān)測點。按照可能由屬性所指定的,可以執(zhí)行另外的一個或多個程序動作。
監(jiān)測點指的是能夠指出指定的數(shù)據(jù)或存儲器部分何時改變的監(jiān)控程序或函數(shù)。例如,Purify中的監(jiān)測點是通過監(jiān)控程序執(zhí)行時其進行加載和存儲的地址來實現(xiàn)的。Purify可以報告有關(guān)讀取、寫入、分配、釋放、進入函數(shù)入口范圍以及離開函數(shù)出口范圍的每次存儲器訪問的準確原因和結(jié)果。
在本發(fā)明的一個實施例中,用戶指定的屬性可以包括于運行時分析工具的配置文件內(nèi)。例如,關(guān)于Purify,指令可以包括于指出特定環(huán)境的配置文件內(nèi),在該特定環(huán)境下監(jiān)測點被自動地創(chuàng)建或者視具體情況而被調(diào)用。
這樣的指令的例子可以是watch on error<error type><stack trace><re-start flag>。當(dāng)在Purify的情況下將該指令放入配置文件中的時候,該指令引起針對由該指令的參數(shù)所指出的環(huán)境而設(shè)置或調(diào)用監(jiān)測點。<errortype>屬性指定了會引起調(diào)用監(jiān)測點功能的特定類型的存儲器訪問錯誤。對于該屬性來說可以指定的可能的運行時存儲器訪問錯誤可以包括、但不限于空閑存儲器讀錯誤、空閑存儲器寫錯誤、存儲器泄漏錯誤、未初始化存儲器讀錯誤、數(shù)組邊界讀錯誤、數(shù)組邊界寫錯誤等。提供不同類型的運行時存儲器訪問錯誤的清單只是為了說明。同樣地,本文所公開的實施例并不打算受限于所提供的實例。應(yīng)當(dāng)認識到,OCI工具能夠識別的任何類型的運行時存儲器訪問錯誤都可以用作error type屬性的可能值。
指令中的下一屬性,<stack trace>屬性可以指定為了調(diào)用監(jiān)測點而要從運行時存儲器訪問錯誤檢測的堆棧跟蹤信息。例如,指令的堆棧跟蹤信息可以指出下次檢測對malloc的調(diào)用,其中從calloc調(diào)用malloc,從main調(diào)用calloc,從_start調(diào)用main,假定該指令的其他條件也滿足,則自動地設(shè)置監(jiān)測點。<re-start flag>屬性指定了當(dāng)調(diào)用監(jiān)測點時是否要重新啟動處于測試中的程序。在另一實施例中,可以提供另外的屬性,其指出當(dāng)設(shè)置監(jiān)測點時是否要在調(diào)試器以及要使用的特定調(diào)試器中重新啟動程序。
因此,當(dāng)檢測到運行時存儲器訪問錯誤的時候,可以將從運行時分析工具收集的信息,即根據(jù)圖3所描述的上下文信息,與配置文件中所包括的用戶指定的指令進行比較。如果檢測到的運行時存儲器訪問錯誤的上下文信息與指令的屬性匹配,則可以自動地創(chuàng)建對應(yīng)于匹配指令的監(jiān)測點。至于Purify運行時分析工具,視具體情況而定,可以將指定了從上下文信息或指令所提取的屬性的指示插入到指示文件(directive file)。如所指出的,處于測試中的程序依照指令屬性所指定的可選地可以隨或不隨調(diào)試器重新啟動。
圖4是說明依照本發(fā)明的一個實施例的運行時存儲器分析方法400的流程圖。例如,方法400可以開始于這樣的狀態(tài),即在該狀態(tài)下已將本文所討論的各種指令中的一個或多個插入到諸如Purify的運行時分析工具的配置文件。如所指出的,指令的屬性可以指定將要調(diào)用或設(shè)置監(jiān)測點功能的環(huán)境。
因此,方法400可從步驟402開始,在步驟402中讀取來自配置文件的指令。在步驟405中,基于OCI的運行時分析工具可以利用運行時存儲器分析函數(shù)插裝計算機程序。例如,Purify插裝程序以自動地將每個存儲器訪問截取為其動態(tài)錯誤檢測的一部分??梢詫\行時例程的一個或多個調(diào)用插入到程序,所述對運行時例程的一個或多個調(diào)用是運行時分析函數(shù)庫部分,而不是處于測試中的程序的原始部分。可以在程序內(nèi)包括、但不限于函數(shù)入口和/或出口點的位置插入這些函數(shù)以監(jiān)控本文所描述的各種類型的存儲器訪問。在步驟410中,運行時分析工具可以讀取來自指示文件的任何指示,所述指示文件已由于處于測試中的計算機程序的一次或多次先前的運行而被啟用??梢岳靡褬俗R的指示實現(xiàn)存儲器訪問監(jiān)控。
在步驟415中,可以執(zhí)行插裝程序。在步驟420中,可以進行關(guān)于是否遇到停止條件的確定。例如,程序可以自然地終止、遇到致命的故障或斷點等。如果沒有遇到停止條件,則該方法可以前進到步驟425。在步驟425中,可以進行關(guān)于是否遇到運行時存儲器訪問錯誤的確定。如果沒有,則該方法可以返回到步驟415繼續(xù)執(zhí)行。如果檢測到運行時存儲器訪問錯誤,則該方法可以前進到步驟430。
在步驟430中,可以通過OCI工具來收集上下文信息。例如,可以確定諸如引起運行時存儲器訪問錯誤的功能和/或模塊的信息以及被訪問的特定的存儲器地址。還可以識別堆棧跟蹤信息以及檢測的存儲器訪問錯誤的類型,所述堆棧跟蹤信息指定了通向造成運行時存儲器訪問錯誤的函數(shù)的調(diào)用鏈。
在步驟435中,可以進行關(guān)于檢測到的運行時存儲器訪問錯誤是否與配置文件中所指定的一個或多個指令的屬性一致的確定。例如,可以在步驟430中所收集的上下文信息和用戶指定指令的一個或多個用戶指定的屬性之間進行比較??梢栽跈z測到的運行時存儲器訪問錯誤的類型和指令中所指定的類型之間、在對引起運行時存儲器訪問錯誤有責(zé)任的函數(shù)和指令中所指定的函數(shù)之間、和/或在檢測到的堆棧跟蹤信息或調(diào)用鏈和指令中所指定的堆棧跟蹤信息或調(diào)用鏈之間進行比較。如果檢測到的運行時存儲器訪問錯誤與配置文件中的指令之一所指定的屬性一致或匹配,則該方法可以前進到步驟440。如果不一致或不匹配,則該方法可以返回到步驟415繼續(xù)執(zhí)行。
應(yīng)當(dāng)認識到,可以從指令中省略本文所討論的有關(guān)指示的一個或多個屬性或者將其指定為通配符。例如,開發(fā)者可以省略對引起運行時存儲器訪問錯誤有責(zé)任的函數(shù)或者將屬性指定為通配符。無論哪種情況,指令都指出有責(zé)任的函數(shù)與是否觸發(fā)監(jiān)測點無關(guān)。如果滿足其他參數(shù),則會動態(tài)地設(shè)置監(jiān)測點而不考慮引起運行時存儲器訪問錯誤的特定函數(shù)。例如,得到的監(jiān)測點會監(jiān)控特定類型的存儲器訪問錯誤而不考慮觸發(fā)錯誤的函數(shù)。類似地,運行時存儲器訪問錯誤的類型可以被忽略或被指定為通配符。在這種情況下,例如,可以識別如指令所指定的特定函數(shù)和/或調(diào)用鏈所觸發(fā)的任何類別的運行時存儲器訪問錯誤,從而實現(xiàn)配置的監(jiān)測點監(jiān)控所指出的函數(shù)的訪問。
總之,在步驟440中,可以動態(tài)地設(shè)置或創(chuàng)建監(jiān)測點??梢詫⒅付擞脩糁噶畹膮?shù)、并且因此指定了上下文信息的指示插入到指示文件。例如,如果指令是“watch_on_error FMM foo;*1”,則該指令指定如果在名為“foo”的函數(shù)中檢測出空閑存儲器失配(FMM)錯誤,則應(yīng)當(dāng)動態(tài)地設(shè)置監(jiān)測點。通配符“*”指出可以從任何地方調(diào)用函數(shù)“foo”。屬性“1”指示將使用可以由開發(fā)者在其它地方指定的特定調(diào)試器來重新啟動程序。得到的可以被插入到指示文件的監(jiān)測點命令或指示可以采取purify_watch_n(<address-of-array>,<size-of-array>,“rw”)的形式,該形式告訴運行時分析工具在用于任何的讀、寫和/或自由訪問的地址監(jiān)視存儲器。
因此,在步驟445中,可以自動地執(zhí)行指令中指定的一個或多個程序動作。例如,如果指令中指定了的話則可以自動地重新啟動程序。另外,如果指令這樣指出了,則可以在用戶指定的調(diào)試器內(nèi)重新啟動程序。也就是說,可以自動地運行調(diào)試器并且可以自動地加載和執(zhí)行程序。
當(dāng)程序重新啟動的時候,最近創(chuàng)建的監(jiān)測點成為有效的并且監(jiān)控對目標存儲器位置的和/或通過目標函數(shù)的存儲器訪問。可以為進一步的分析收集并且存儲運行時存儲器訪問信息和/或以別的方式使其對于用戶可用。
本文所公開的方法描述了本發(fā)明的一個實施例,并且同樣地,其不打算以任何的方式來限制本發(fā)明。本發(fā)明的其它實施例,如可以由本領(lǐng)域的技術(shù)人員所設(shè)想的也在本發(fā)明的范圍之內(nèi)。作為一個例子,諸如多線程、面向?qū)ο蟮某绦蛟O(shè)計等程序設(shè)計習(xí)慣的應(yīng)用可能導(dǎo)致不同的步驟以不同于所提供的次序而被并發(fā)地執(zhí)行,或者以一些其它的方式而被改變。然而,這樣的差異并不背離本發(fā)明的精神。
可以以硬件、軟件或者硬件和軟件的結(jié)合來實現(xiàn)本發(fā)明。可以在一個計算機系統(tǒng)中以集中式的方式或者在不同的元件分散于幾個互連的計算機系統(tǒng)的情況下以分布式的方式來實現(xiàn)本發(fā)明。適于實現(xiàn)本文所描述的方法的任何類型的計算機系統(tǒng)或其它的裝置都是適合的。硬件和軟件的典型的結(jié)合可以是具有計算機程序的通用計算機系統(tǒng),當(dāng)加載和執(zhí)行該計算機程序的時候,其控制計算機系統(tǒng)從而使得該計算機系統(tǒng)實現(xiàn)本文所描述的方法。還可以將本發(fā)明嵌入到計算機程序產(chǎn)品中,其包括能實現(xiàn)本文所描述的方法的全部特征,并且當(dāng)加載到計算機系統(tǒng)的時候其能夠?qū)崿F(xiàn)這些方法。
在當(dāng)前上下文中,術(shù)語“計算機程序”、“軟件”、“應(yīng)用”、其變型和/或組合,表示這樣一組指令以任何語言、代碼或符號的任何表達,即該組指令想要使得具有信息處理能力的系統(tǒng)直接地或者在下述其一或二者之后執(zhí)行特定的功能a)轉(zhuǎn)換成另一種語言、代碼或符號;b)以不同材料的形式再現(xiàn)。例如,計算機程序可以包括、但不限于子例程、函數(shù)、過程、對象方法、對象實現(xiàn)、可執(zhí)行應(yīng)用、小應(yīng)用程序、小服務(wù)程序、源代碼、目標代碼、共享庫/動態(tài)負載庫和/或設(shè)計用于在計算機系統(tǒng)上執(zhí)行的其它指令序列。
術(shù)語“一”和“一個”,如本文所使用的,被定義為一個或多于一個。術(shù)語“多個”,如本文所使用的,被定義為兩個或多于兩個。術(shù)語“另一個”,如本文所使用的,被定義為至少第二個或更多。術(shù)語“包含”和/或“具有”,如本文所使用的,被定義為包括(即開放語言)。術(shù)語“連接”,如本文所使用的,盡管不一定直接連接,也不一定機械連接,但仍被定義為連接,即通過通信通道或路徑或另一組件或系統(tǒng)進行通信鏈接。
可以以其它的形式實施本發(fā)明而不背離本發(fā)明的精神或?qū)嵸|(zhì)屬性。因此,當(dāng)指出本發(fā)明的范圍的時候,應(yīng)當(dāng)參考下面的權(quán)利要求,而不是前述的說明書。
權(quán)利要求
1.一種分析計算機程序中運行時存儲器訪問錯誤的方法,所述方法包括利用運行時分析代碼插裝所述計算機程序;檢測所述已插裝的計算機程序的運行時存儲器訪問錯誤;以及響應(yīng)于檢測所述運行時存儲器訪問錯誤,動態(tài)地設(shè)置監(jiān)測點。
2.根據(jù)權(quán)利要求1的方法,所述檢測步驟進一步包括為所述運行時存儲器訪問錯誤確定上下文信息;以及將所述上下文信息與用戶指定的屬性進行比較。
3.根據(jù)權(quán)利要求2的方法,所述動態(tài)地設(shè)置步驟進一步包括根據(jù)、至少部分地根據(jù)所述比較步驟選擇性地設(shè)置所述監(jiān)測點。
4.根據(jù)權(quán)利要求2的方法,其中,所述上下文信息包括一類檢測到的運行時存儲器訪問錯誤并且所述屬性包括用戶指定類型的運行時存儲器訪問錯誤,所述比較步驟進一步包括將檢測到的運行時存儲器訪問錯誤的類型與用戶指定的運行時存儲器訪問錯誤的類型進行比較。
5.根據(jù)權(quán)利要求2的方法,其中,所述上下文信息包括用于檢測到的運行時存儲器訪問錯誤的堆棧跟蹤信息并且所述屬性包括用戶指定的堆棧跟蹤信息,所述比較步驟進一步包括將用于檢測到的運行時存儲器訪問錯誤的堆棧跟蹤信息與用戶指定的堆棧跟蹤信息進行比較。
6.根據(jù)權(quán)利要求1的方法,其進一步包括選擇性地重新啟動所述具有啟用的監(jiān)測點的已插裝的計算機程序。
7.根據(jù)權(quán)利要求1的方法,其進一步包括利用調(diào)試器來選擇性地重新啟動所述具有啟用的監(jiān)測點的已插裝的計算機程序。
8.一種分析計算機程序中運行時存儲器訪問錯誤的方法,所述方法包括檢測計算機程序中的運行時存儲器訪問錯誤;為所述運行時存儲器訪問錯誤確定上下文信息;將所述上下文信息與用戶指定的屬性進行比較;以及如果所述上下文信息與用戶指定的屬性匹配,則為所述計算機程序動態(tài)地設(shè)置監(jiān)測點。
9.根據(jù)權(quán)利要求8的方法,其中,所述上下文信息包括一類檢測到的運行時存儲器訪問錯誤并且所述屬性指定了用戶指定類型的運行時存儲器訪問錯誤,所述比較步驟進一步包括將檢測到的運行時存儲器訪問錯誤的類型與用戶指定的運行時存儲器訪問錯誤的類型進行比較。
10.根據(jù)權(quán)利要求8的方法,其中,所述上下文信息包括用于檢測到的運行時存儲器訪問錯誤的堆棧跟蹤信息并且所述屬性指定了用戶指定的堆棧跟蹤信息,所述比較步驟進一步包括將用于所述檢測到的運行時存儲器訪問錯誤的堆棧跟蹤信息與所述用戶指定的堆棧跟蹤信息進行比較。
11.根據(jù)權(quán)利要求8的方法,其進一步包括選擇性地重新啟動具有啟用的監(jiān)測點的已插裝的計算機程序。
12.根據(jù)權(quán)利要求8的方法,其進一步包括利用調(diào)試器來選擇性地重新啟動具有啟用的監(jiān)測點的已插裝的計算機程序。
13.根據(jù)權(quán)利要求8的方法,其進一步包括利用運行時分析代碼插裝所述計算機程序。
14.一種包括用于實現(xiàn)前述方法權(quán)利要求中任何一項所述的方法的裝置的系統(tǒng)。
全文摘要
一種分析計算機程序中運行時存儲器訪問錯誤的方法,該方法可以包括利用運行時分析代碼插裝所述計算機程序并且檢測已插裝的計算機程序的運行時存儲器訪問錯誤。響應(yīng)于檢測所述運行時存儲器訪問錯誤,該方法還可以包括動態(tài)地設(shè)置監(jiān)測點。
文檔編號G06F11/36GK1991785SQ20061014702
公開日2007年7月4日 申請日期2006年11月13日 優(yōu)先權(quán)日2005年12月27日
發(fā)明者T·沃拉 申請人:國際商業(yè)機器公司