日韩免费在线观看成人,骚碰成人免费视频,电影院 摸 湿 嗯…啊h

    1. <span id="um726"><blockquote id="um726"></blockquote></span>

        <span id="um726"><blockquote id="um726"></blockquote></span>
        1. 您的位置:首頁>世界杯 >內(nèi)容

          天天樂斗地主 (關(guān)于天天樂斗地主 玩法)

          2022-11-23 14:35:33來源:世界杯
          導讀 ?Dr. Memory 是一個開源免費的內(nèi)存檢測工具,它能夠及時發(fā)現(xiàn)內(nèi)存相關(guān)的編程錯誤,比如未初始化訪問、內(nèi)存非法訪問以及內(nèi)存泄露等。它不...

          ?Dr. Memory 是一個開源免費的內(nèi)存檢測工具,它能夠及時發(fā)現(xiàn)內(nèi)存相關(guān)的編程錯誤,比如未初始化訪問、內(nèi)存非法訪問以及內(nèi)存泄露等。它不僅能夠在 Linux 下面工作,也能在微軟的 Windows 操作系統(tǒng)上工作。不過,本文撰寫時,DrMemory 僅能支持 32 位程序,這是它的一個巨大缺陷,但相信隨著開發(fā)的進行,DrMemory 會推出支持 位程序的版本。

          Dr Memory 與 Valgrind 類似,可以直接檢查已經(jīng)編譯好的可執(zhí)行文件。用戶不用改寫被檢查程序的源代碼,也無須重新鏈接第三方庫文件,使用起來非常方便。

          易用性和性能是 DrMemory 的主要優(yōu)點,此外 DrMemory 可以用于調(diào)試 Windows 程序,因此它被廣泛認為是 Windows 上的 Valgrind 替代工具。在 Linux 平臺中,DrMemory 也往往可以作為 Valgrind 之外的另一個選擇。

          DrMemory 對內(nèi)存泄露的監(jiān)測采用了比較獨特的算法,大量減少了”false positive”,即虛假錯誤。如果您使用 Valgrind 等工具后仍無法找到程序中的內(nèi)存錯誤,不妨試試 DrMemory 吧。

          Dr. Memory 建立在 DynamoRIO 這個動態(tài)二進制插樁平臺上。動態(tài)監(jiān)測程序的運行,并對內(nèi)存訪問相關(guān)的執(zhí)行代碼進行動態(tài)修改,記錄其行為,并采用先進的算法進行錯誤檢查。

          C++程序員最大的敵人就是內(nèi)存處理錯誤,比如內(nèi)存泄露、內(nèi)存溢出等。這些錯誤不易發(fā)現(xiàn),調(diào)試困難。本文介紹一個新的內(nèi)存調(diào)試工具 DrMemory,為您的工具箱中添加一個新的內(nèi)存檢查利器吧。

          Dr. Memory 建立在 DynamoRIO 這個動態(tài)二進制插樁平臺上。動態(tài)監(jiān)測程序的運行,并對內(nèi)存訪問相關(guān)的執(zhí)行代碼進行動態(tài)修改,記錄其行為,并采用先進的算法進行錯誤檢查。

          根據(jù) DrMemory 開發(fā)人員發(fā)表在 CGO 2011上的論文 Practical Memory Checking with Dr. Memory,DrMemory 對程序的正常執(zhí)行影響較小,這在同類工具中是比較領(lǐng)先的。其 performance 和 Valgrind 的比較如圖 1 所示(圖片源自 DrMemory 主頁):

          圖 1. 和 Valgrind 的性能比較

          Valgrind 對程序的正常運行影響較大,一般來說如果進行全面內(nèi)存檢測,會使程序的運行速度有 50 到 300 倍的減慢。而 DrMemory 在這個方面則有一定的優(yōu)勢。

          易用性和性能是 DrMemory 的主要優(yōu)點,此外 DrMemory 可以用于調(diào)試 Windows 程序,因此它被廣泛認為是 Windows 上的 Valgrind 替代工具。在 Linux 平臺中,DrMemory 也往往可以作為 Valgrind 之外的另一個選擇。

          DrMemory 對內(nèi)存泄露的監(jiān)測采用了比較獨特的算法,大量減少了”false positive”,即虛假錯誤。如果您使用 Valgrind 等工具后仍無法找到程序中的內(nèi)存錯誤,不妨試試 DrMemory 吧。

          Windows 上 DrMemory 提供了可執(zhí)行安裝包,只需點擊下一步,即可安裝完畢。

          DrMemory,第一印象 DrMemory 的使用很簡單,可以說它是傻瓜式。正常運行一個程序時,我們在 shell 中敲入命令然后回車。為了用 DrMemory 檢查,只需要在

          Hello DrMemory,第一印象

          DrMemory 的使用很簡單,可以說它是傻瓜式。正常運行一個程序時,我們在 shell 中敲入命令然后回車。為了用 DrMemory 檢查,只需要在正常命令之前加入 drmemory.pl,比如程序檢查程序 t,那么就這樣:

          在計算機領(lǐng)域,Helloworld 總是第一個程序。讓我們寫一個 HelloDrMemory,來和 DrMemory 簡單接觸一下吧。

          清單 1,Hello DrMem 例子程序

          很明顯,有 50 個內(nèi)存泄露,都在同一行代碼中(Line 8)。讓我們用 Dr Memory 來檢查它。

          屏幕上會有如上所示的錯誤匯總,注意看 ERRORS FOUND 下面的第 5 行:”50 total leaks”。不錯吧。根據(jù)提示,更多的細節(jié)被寫入一個 result 文本文件。打開并查看該文件,就可以知道程序在哪里出現(xiàn)了內(nèi)存錯誤了。真是太方便了。不過 result 文件是否容易閱讀呢?下面我們來詳細解釋如何閱讀 DrMemory 產(chǎn)生的 result 文件。

          DrMemory 報告解讀細節(jié)

          內(nèi)存非法訪問

          DrMemory 認為任何對未分配內(nèi)存區(qū)域的讀寫都是非法的。在 Linux 中,應(yīng)用程序可以用以下幾個方式分配內(nèi)存:

          調(diào)用 mmap (或者 mremap)

          調(diào)用 malloc 在堆上分配內(nèi)存

          使用 alloca 在棧上分配內(nèi)存

          非法訪問就是對以上三種方法分配的內(nèi)存區(qū)域之外進行的訪問。常見的問題包括 buffer overflow、數(shù)組越界、讀寫已經(jīng) free 的內(nèi)存、堆棧溢出等等。讓我們測試下面這個問題程序。

          Buffer overflow

          例子程序的第 5 到 6 行存在 buffer overflow。在內(nèi)存中,buffer 的分布如下圖所示:

          圖 2. Buffer 分布

          訪問 x+8 將產(chǎn)生一個非法內(nèi)存訪問。對此,Dr Memory 將給出如下的錯誤信息:

          首先用大寫的單詞 UNADDRESSABLE ACCESS 表明這是一個非法訪問錯誤。接著,“reading 0x0804a020-0x0804a021 1 byte(s)”表示這是一個非法讀,讀取的范圍為 0x0804a020 到 0x0804a021,一共讀了 1 個 byte。接下來的三行是調(diào)用堆棧信息,可以方便地看到錯誤發(fā)生在哪個源文件的哪一行(程序 t 需要在用 gcc 編譯的時候給定-g 選項)。此外 DrMemory 還給出了一些輔助的錯誤信息。比如:

          錯誤發(fā)生的時間:Note: elapsed time = 0:00:00.133 in thread 13971。這表明錯誤是程序開始的第 0.133 秒后發(fā)生的,有些情況下,人們可以根據(jù)這個時間進行輔助判斷。

          錯誤細節(jié):Note: refers to 1 byte(s) beyond last valid byte in prior malloc。這里給出了錯誤的詳細信息,如前所述,造成非法訪問的可能很多,在本例中是 buffer overflow,因此這里的詳細信息可以幫助我們了解非法訪問的具體原因。

          Note: prev lower malloc: 0x0804a018-0x0804a020。這里給出了 overflow 之前的合法內(nèi)存地址,有些情況下對于查錯 有一定的幫助。

          Note: instruction: movzx (%eax) ->%eax。這里給出的是造成錯誤的具體指令。

          可以看到 DrMemory 只報告了一個未初始化讀錯誤,在第 12 行。很多其他工具對于 memcpy(&b,&a, sizeof(T))也會報錯。

          GCC 將自動對齊數(shù)據(jù)結(jié)構(gòu)(未使用 pack 修飾符的情況下)。因此 struct T 在內(nèi)存中的實際分布如下:

          圖 3. 內(nèi)存拷貝細節(jié)

          在 memcpy 時,有 3 個未初始化 byte 也被訪問了,但這類錯誤如果也報告的話,對正常程序 DrMemory 會產(chǎn)生很多錯誤信息。這些其實不是錯誤,所以被稱為 False Positive。類似醫(yī)學名詞“假陽性”。內(nèi)存調(diào)試工具的一個主要目標就是減少 False Positive,否則產(chǎn)生的報告有用性將極大降低。

          其它很多工具,遇到上述拷貝會報告 false positive,浪費讀報告的人們的時間。因此這是 Dr Memory 的一個重要優(yōu)點。

          內(nèi)存泄露

          內(nèi)存泄露是常見的內(nèi)存錯誤,我們可能都曾經(jīng)遇到過。不過 Dr.Memory 對內(nèi)存泄露的定義比較獨特,在程序退出之前,Dr.Memory 把所有依然被分配的內(nèi)存分為三類:

          Still-reachable allocation

          很多程序分配了內(nèi)存之后,在其整個生命周期內(nèi)都不釋放。雖然這是一種泄露,但實際上多數(shù)情況下這是無害的,甚至是特意這樣設(shè)計的。因此 Dr.Memory 并不認為這是一種內(nèi)存泄露,而稱之為”Still-reachable allocation”。

          Leak

          有一些內(nèi)存無法再被釋放,因為指向該內(nèi)存的指針丟失了。比如下面這個代碼:

          清單 5.內(nèi)存 Leak 例子代碼

          DrMemory 稱這類錯誤為內(nèi)存泄露。因為這些內(nèi)存已經(jīng)沒有辦法被釋放了。

          Possible Leak

          如前所述指向內(nèi)存的指針被修改會被認為是一個 Leak,但并非所有的指針修改都是一個 Leak。DrMemory 利用一些經(jīng)驗規(guī)則(Heuristic)將以下幾種指針修改列為 Possible Leak。

          第一種情況:C++程序利用 new[]分配了一個數(shù)組,該數(shù)組的每個元素都是 擁有自己的析構(gòu)函數(shù)的復雜數(shù)據(jù)結(jié)構(gòu)。這種情況下,New 操作符為每個元素加上一個 header 用來保存數(shù)組的個數(shù),以便 delete[]操作符知道需要調(diào)用多少個析構(gòu)函數(shù)。但 new[]返回 caller 的是 header 之后的地址,這樣就變成了一個 mid-allocation 指針。這可能被 Dr memory 認為是一個內(nèi)存泄露。但可以使用-no_midchunk_new_ok 選項讓 DrMemory 將這類錯誤報告為”possible leak”而非”leak”。

          參考下圖,理解這種情況。

          圖 4.mid-chunk new

          從堆分配器的角度來看,buffer 的起點在 A 處,但 new 返回 B,給 Object 變量賦值。從某種角度上看,指針 A 丟失了,是一個 leak,但實際上,當調(diào)用 delete []操作符時,C++運行時庫會自動將 Object 指針減 4,從而指向 A 點,再進行釋放。某些編譯器不使用這種做法,則沒有這個問題。

          第二種情況,某些 C++編譯器在處理多繼承時,會出現(xiàn) mid-chunk 指針。很抱歉,具體細節(jié)本人也不甚了解。Dr Memory 的原文如下:it includes instances of a pointer to a class with multiple inheritance that is cast to one of the parents: it can end up pointing to the subobject representation in the middle of the allocation. 您可以用-no_midchunk_inheritance_ok 選項將這類“錯誤”報告為”possible leak” 。

          還有一種可能:std::string 類把一個 char[]數(shù)組放置在分配空間中,并返回一個指針直接指向它,造成了一個 mid-allocation 指針。您可以用-no_midchunk_string_ok 選項讓這類錯誤顯示為”possible leak”。

          現(xiàn)實世界中真正的程序有很多不同于本文中所羅列的那些例子程序,現(xiàn)實程序更復雜,查找錯誤并不像例子所示的那么容易。DrMemory 設(shè)計了一些輔助選項,靈活使用它們才能在真正的工作中得到有用的信息。

          監(jiān)控子程序

          缺省情況下 DrMemory 將監(jiān)控當前進程產(chǎn)生的子進程的內(nèi)存錯誤。如果您想禁止檢查子進程,可以使用-no_follow_children 選項。

          合并檢查結(jié)果

          用-aggregate 選項可以合并 DrMemory 的檢查結(jié)果,比如下面的命令把 logs 目錄下面多個 DrMemory 報告合并為一個總的報告。

          這個功能在某些情況下比較有用。比如對同一個程序用多個不同的測試用例測出不同的內(nèi)存錯誤,可以把多個報告合并起來,以便程序員一次閱讀。

          檢查不退出程序

          一些程序永遠或者長時間都不退出,對于某些內(nèi)存錯誤,比如未初始化讀寫,或者非法讀寫,DrMemory 一旦發(fā)現(xiàn)就立即寫入 result 文件。但 DrMemory 只有在進程退出時才檢查內(nèi)存泄露。因此對于長期運行的程序,如果我們想在其運行期間得到內(nèi)存泄露的報告,就需要使用 DrMemory 的 nudge 命令。比如您的進程 pid 為 1000,正在被 DrMemory 檢測。那么你可以在 Shell 中運行下面這條命令,強制 DrMemory 進行內(nèi)存泄露檢查,并把結(jié)果更新到 result 文件中。

          現(xiàn)在打開 result 文件,如果程序有內(nèi)存泄露,您將在該文件中找到錯誤信息。

          Suppressing Errors

          內(nèi)存錯誤檢查工具的一個重要能力就是能夠 suppress errors,即隱藏指定”錯誤”的能力。因為人們使用內(nèi)存錯誤檢測工具最希望的是它能給出“真正的”錯誤,而不是給出大量的不是錯誤的錯誤。工具本身可以根據(jù)一些經(jīng)驗算法隱藏一些“眾所周知”的假錯誤。但更多的情況下,需要使用者告訴工具如何區(qū)分出假錯誤。

          每次運行 DrMemory 時,它會產(chǎn)生一個 suppress 文件,和 result 文件放在一起。該文件的格式如下:

          圖 5. suppress 文件格式

          suppress 文件有多個”O(jiān)ne Error”小節(jié)組成,每個”O(jiān)ne Error”表示一個可以被 suppress 的錯誤。用調(diào)用堆棧來表示,有兩種格式來表示堆棧:

          DrMemory 支持通配符,比如 t!*表示不報告所有模塊 t 中的錯誤。在 Linux 下面,模塊 t,就是由 t.c 生成的 t.o 所包含的代碼,換句話說就是不檢查 t.c 中的錯誤。

          一些有用的選項:

          現(xiàn)實世界中真正的程序有很多不同于本文中所羅列的那些例子程序,現(xiàn)實程序更復雜,查找錯誤并不像例子所示的那么容易。DrMemory 設(shè)計了一些輔助選項,靈活使用它們才能在真正的工作中得到有用的信息。

          監(jiān)控子程序

          缺省情況下 DrMemory 將監(jiān)控當前進程產(chǎn)生的子進程的內(nèi)存錯誤。如果您想禁止檢查子進程,可以使用-no_follow_children 選項。

          合并檢查結(jié)果

          用-aggregate 選項可以合并 DrMemory 的檢查結(jié)果,比如下面的命令把 logs 目錄下面多個 DrMemory 報告合并為一個總的報告。

          這個功能在某些情況下比較有用。比如對同一個程序用多個不同的測試用例測出不同的內(nèi)存錯誤,可以把多個報告合并起來,以便程序員一次閱讀。

          檢查不退出程序

          一些程序永遠或者長時間都不退出,對于某些內(nèi)存錯誤,比如未初始化讀寫,或者非法讀寫,DrMemory 一旦發(fā)現(xiàn)就立即寫入 result 文件。但 DrMemory 只有在進程退出時才檢查內(nèi)存泄露。因此對于長期運行的程序,如果我們想在其運行期間得到內(nèi)存泄露的報告,就需要使用 DrMemory 的 nudge 命令。比如您的進程 pid 為 1000,正在被 DrMemory 檢測。那么你可以在 Shell 中運行下面這條命令,強制 DrMemory 進行內(nèi)存泄露檢查,并把結(jié)果更新到 result 文件中。

          現(xiàn)在打開 result 文件,如果程序有內(nèi)存泄露,您將在該文件中找到錯誤信息。

          Suppressing Errors

          內(nèi)存錯誤檢查工具的一個重要能力就是能夠 suppress errors,即隱藏指定”錯誤”的能力。因為人們使用內(nèi)存錯誤檢測工具最希望的是它能給出“真正的”錯誤,而不是給出大量的不是錯誤的錯誤。工具本身可以根據(jù)一些經(jīng)驗算法隱藏一些“眾所周知”的假錯誤。但更多的情況下,需要使用者告訴工具如何區(qū)分出假錯誤。

          每次運行 DrMemory 時,它會產(chǎn)生一個 suppress 文件,和 result 文件放在一起。該文件的格式如下:

          圖 5. suppress 文件格式

          suppress 文件有多個”O(jiān)ne Error”小節(jié)組成,每個”O(jiān)ne Error”表示一個可以被 suppress 的錯誤。用調(diào)用堆棧來表示,有兩種格式來表示堆棧:

          DrMemory 支持通配符,比如 t!*表示不報告所有模塊 t 中的錯誤。在 Linux 下面,模塊 t,就是由 t.c 生成的 t.o 所包含的代碼,換句話說就是不檢查 t.c 中的錯誤。

          天天樂斗地主
          免責聲明:本文由用戶上傳,如有侵權(quán)請聯(lián)系刪除!

          猜你喜歡

          最新文章