C畢業(yè)設(shè)計(jì)外文翻譯
《C畢業(yè)設(shè)計(jì)外文翻譯》由會(huì)員分享,可在線閱讀,更多相關(guān)《C畢業(yè)設(shè)計(jì)外文翻譯(7頁(yè)珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。
1、Fixing Memory Problems This chapter is about finding bugs in C/C++ programs with the help of a memory debugger. A memory debugger is a runtime tool designed to trace and detect bugs in C/C++ memory management and access. It does not replace a general debugger. In the following sections, we will
2、describe the memory access bugs that typically occur in C/C++ programs, introduce memory debuggers, and show with two examples how these tools find bugs. We will then show how to run memory and source code debuggers together, how to deal with unwanted error messages by writing a suppression file
3、, and what restrictions need to be considered. 4.1 Memory Management in C/C++ – Powerful but Dangerous The C/C++ language is able to manage memory resources, and can access memory directly through pointers. Efficient memory handling and “programming close to the hardware” are reasons why C/C++ r
4、eplaced assembly language in the implementation of large software projects such as operating systems, where performance and low overhead play a major role. The allocation of dynamic memory (also known as heap memory) in C/C++ is under the control of the programmer. New memory is allocated with f
5、unctions such as malloc() and various forms of the operator new. Unused memory is returned with free() or delete. The memory handling in C/C++ gives a large degree of freedom, control, and performance, but comes at a high price: the memory access is a frequent source of bugs. The most frequent s
6、ources of memory access bugs are memory leaks, incorrect use of memory management, buffer overruns, and reading uninitialized memory. 33 34 4 Fixing Memory Problems 4.1.1 Memory Leaks Memory leaks are data structures that are allocated at runtime, but not deallocated once they are no longer ne
7、eded in the program. If the leaks are frequent or large, eventually all available main memory in your computer will be consumed. The program will first slow down, as the computer starts swapping pages to virtual memory, and then fail with an out-of-memory error. Finding leaks with a general debug
8、ger is difficult because there is no obvious faulty statement. The bug is that a statement is missing or not called. 4.1.2 Incorrect Use of Memory Management A whole class of bugs is associated with incorrect calls to memory management: freeing a block of memory more than once, accessing memory
9、 after freeing it, or freeing a block that was never allocated. Also belonging to this class is using delete instead of delete[] for C++ array deallocation, as well as using malloc() together with delete, and using new together with free(). 4.1.3 Buffer Overruns Buffer overruns are bugs where m
10、emory outside of the allocated boundaries is overwritten, or corrupted. Buffer overruns can occur for global variables, local variables on the stack, and dynamic variables that were allocated on the heap with memory management. One nasty artifact of memory corruption is that the bug may not beco
11、me visible at the statement where the memory is overwritten. Only later, another statement in the program will access this memory location. Because the memory location has an illegal value, the program can behave incorrectly in a number of ways: the program may compute a wrong result, or, if the
12、 illegal value is in a pointer, the program will try to access protected memory and crash. If a function pointer variable is overwritten, the program will do a jump and try to execute data as program code. The key point is that there may be no strict relation between the statement causing the me
13、mory corruption and the statement triggering the visible bug. 4.1.4 Uninitialized Memory Bugs Reading uninitialized memory can occur because C/C++ allows creation of variables without an initial value. The programmer is fully responsible to initialize all global and local variables, either throu
14、gh assignment statements or through the 4.2 Memory Debuggers to the Rescue 35 various C++ constructors. The memory allocation function malloc() and operator new also do not initialize or zero out the allocated memory blocks. Uninitialized variables will contain unpredictable values. 4.2 Memory
15、Debuggers to the Rescue The above categories of memory access bugs created a need for adequate debugging tools. Finding bugs related to leaked, corrupted, or uninitialized memory with a conventional debugger such as GDB turned out to be unproductive. To deal with memory leaks in large software p
16、rojects, many programmers came up with the same idea. They created memory management functions/operators with special instrumentation to track where a memory block was allocated, and if each block was properly deallocated at the end of the program. Since everybody had the same memory bugs in the
17、ir C/C++ programs, and since everybody improvised with custom instrumentation to track down at least some of these bugs, a market for a tool called memory debugger was created. The most wellknown tool is Purify, released in 1991 by Pure Software. Purify’s name has since become synonymous with me
18、mory debugging. There is also Insure++, Valgrind, and BoundsChecker, among others. See the tools Appendix B.4 starting on page 198 for references and the survey in [Luecke06] for a comparison of features. Memory debuggers do detailed bookkeeping of all allocated/deallocated dynamic memory. They
19、also intercept and check access to dynamic memory. Some memory debuggers can check access to local variables on the stack and statically allocated memory. Purify and BoundsChecker do this by object code instrumentation at program link time, Insure++ uses source code instrumentation, and Valgrind
20、executes the program on a virtual machine and monitors all memory transactions. The code instrumentation allows the tools to pinpoint the source code statement where a memory bug occurred. The following bugs are detectable by a memory debugger: ? Memory leaks ? Accessing memory that was alread
21、y freed ? Freeing the same memory location more than once ? Freeing memory that was never allocated ? Mixing C malloc()/free()with C++ new/delete ? Using delete instead of delete[] for arrays ? Array out-of-bound errors ? Accessing memory that was never allocated ? Uninitialized memory read
22、? Null pointer read or write We will show in the next section how to attach a memory debugger to your program, and how the tool finds and reports bugs. 36 4 Fixing Memory Problems 4.3 Example 1: Detecting Memory Access Errors Our first example is a program that allocates an array in dynamic mem
23、ory, accesses an element outside the final array element, reads an uninitialized array element, and finally forgets to deallocate the array. We use the public domain tool Valgrind on Linux as the memory debugger, and demonstrate how the tool automatically detects these bugs. This is the code of
24、our program main1.c:
1 /* main1.c */
2 #include
25、(n=0;n
26、heck=yes ./a.out In the following sections we go through the error list reported by Valgrind. 4.3.1 Detecting an Invalid Write Access The first – and perhaps most severe – error is a buffer overrun: the accidental write access to array element A[100]. Because the array has only 100 elements, the
27、 highest valid index is 99. A[100] points to unallocated memory that is located just after the memory allocated for array A. Valgrind thus reports an “invalid write” error: ==11323== Invalid write of size 4 ==11323== at 0x8048518: main (main1.c:9) ==11323== Address 0x1BB261B8 is 0 bytes after
28、a block ==11323== of size 400 alloc’d ==11323== at 0x1B903F40: malloc ==11323== (in /usr/lib/valgrind/vgpreload_memcheck.so) ==11323== by 0x80484F2: main (main1.c:6) The string "==11323==" refers to the process ID and is useful when Valgrind is checking multiple processes 1. The important piec
29、e of information is that an invalid 1 Valgrind will, per default, check only the first (parent) process that has been invoked. Use option --trace-children=yes to check all child processes as well. 4.3 Example 1: Detecting Memory Access Errors 37 write occurs in line 9 of main1.c. There is also a
30、dditional information revealing the address of the closest allocated memory block and how it was allocated. The memory debugger guesses that the invalid write in line 9 is related to this memory block. The guess is correct because both belong to the same array A. Note that Valgrind is able to ca
31、tch an out-of-array-bounds errors only when the array is allocated as dynamic memory with malloc() or new. This is the case in the example with the statement in line 6: 6 int* A = (int*)malloc( sizeof(int)*size ); If the example were instead written as int A[size] in line 6, then A would be a l
32、ocal variable located on the stack and not on the heap. It turns out that Valgrind does not detect such an error but Purify is able to catch it. This shows that not all memory debuggers will report exactly the same errors. 修正內(nèi)存問題 本章是關(guān)于利用內(nèi)存BUG調(diào)試器的幫助,來發(fā)現(xiàn)C或C++程序中的BUG。內(nèi)存調(diào)試器是在C或C++程序管理或存儲(chǔ)
33、時(shí)用于追蹤和發(fā)現(xiàn)BUG的運(yùn)行時(shí)工具。它不能取代一個(gè)正規(guī)的調(diào)試器。在一下的章節(jié),我們將描述幾個(gè)代表性的在C或C++程序中處理的內(nèi)容BUG,介紹內(nèi)容調(diào)試器,并且介紹兩個(gè)內(nèi)存如何發(fā)現(xiàn)BUG的例子。我們?nèi)缓髮⒀菔救绾问箖?nèi)存與編碼調(diào)試器一起運(yùn)行,怎么去處理不需要的錯(cuò)誤信息通過寫文件,需要去考慮程序需要的限制。 4.1 內(nèi)存管理在C或C++中強(qiáng)健但是危險(xiǎn) C或C++語(yǔ)言能夠管理內(nèi)存資源,并且通過指針直接讀取內(nèi)存。高效的內(nèi)存處理和“直接控制硬件”是規(guī)劃大型例如操作系統(tǒng)的軟件工程取代匯編語(yǔ)言的原因,高性能和低限制是它作為一個(gè)重要角色的原因。動(dòng)態(tài)內(nèi)存的分配(眾所周知的堆內(nèi)存)在C或C++中是在程序員的控制之
34、下的。新內(nèi)存被分配擔(dān)任起例如malloc()和各種有程序員構(gòu)成的新的指針。不被使用的內(nèi)存被free()或delete回收。 4.1.1 內(nèi)存泄漏 內(nèi)存泄漏是在運(yùn)行時(shí)的內(nèi)存分配結(jié)構(gòu),但是它們只需要我們分配一次,我們卻分配了多次。如果內(nèi)存泄漏經(jīng)常發(fā)生或者十分巨大,最后你電腦的主要內(nèi)存將被耗盡。程序首先會(huì)變慢,然后電腦開始使用分頁(yè)技術(shù)虛擬內(nèi)存,然后以內(nèi)存溢出錯(cuò)誤宣告失敗。用普遍的調(diào)試器發(fā)現(xiàn)內(nèi)存溢出錯(cuò)誤是困難的因?yàn)樗鼪]有一個(gè)明顯的錯(cuò)誤聲明。BUG會(huì)丟失或不能被聲明。 4.1.2 錯(cuò)誤的內(nèi)存管理用法 一套完整BUG集合與錯(cuò)誤聲明對(duì)于內(nèi)存管理來說:解除一個(gè)錯(cuò)誤的內(nèi)存超過一次,在解除以后訪問內(nèi)存,或
35、解除一個(gè)從分配過的阻塞內(nèi)存。用delete代替delete[]在C++數(shù)組中也屬于這個(gè)類,也可以用malloc()和delete一起使用,用new和free()一起使用。 4.1.3 緩存溢出 緩存溢出內(nèi)存被重載時(shí)超出范圍的BUG,或損壞。緩存溢出會(huì)由屬性引起,在堆中的局部變量,通過內(nèi)存管理分配在棧上的動(dòng)態(tài)變量。 在內(nèi)存中令人討厭的事是內(nèi)存重載的時(shí)候BUG沒有被聲明。只有在以后,另一個(gè)在問題中的聲明將存取在內(nèi)存中。因?yàn)閮?nèi)存含有一個(gè)不合法的變量,內(nèi)存會(huì)在一下幾個(gè)方面表現(xiàn)出異常:這個(gè)問題得出一個(gè)錯(cuò)誤的結(jié)果,或者如果一個(gè)不合法的值在指針上,這個(gè)問題將試圖存取和保護(hù)內(nèi)存。如果在存取的過程中一個(gè)動(dòng)
36、態(tài)指針可變,程序?qū)⑻幚硭凑粘绦虼a。鍵指針不是引起內(nèi)存溢出和嚴(yán)重問題的關(guān)鍵。 4.1.4 非原始內(nèi)存BUG 讀非原始內(nèi)存是因?yàn)镃或C++允許創(chuàng)建變量在沒有一個(gè)原始值的情況下。程序員有完全的責(zé)任給所有的屬性和局部變量賦值,也可以通過聲明,或各種C++的構(gòu)造器。內(nèi)存引導(dǎo)功能malloc()和操作new也不能夠定義變量或者是內(nèi)存為空。未定義的變量中包含不穩(wěn)定的值。 4.2 內(nèi)存調(diào)試解決 上述問題處理BUG需要?jiǎng)?chuàng)建一個(gè)強(qiáng)大的BUG處理工具。尋找BUG與漏洞有關(guān),不完善的,只有普通BUG調(diào)試器GDB內(nèi)存變得不安全。應(yīng)付大型軟件工程中的系統(tǒng)漏洞,很多程序員都提出了相同的意見。他們建立內(nèi)存管理機(jī)制
37、為一個(gè)被分配阻塞內(nèi)存利用不同的機(jī)制,并且確保是否每個(gè)阻塞內(nèi)存在最后都得到了分配。 自從每個(gè)人在各自的C或C++程序中遇到相同的內(nèi)存BUG,自從每個(gè)人用傳統(tǒng)的內(nèi)存處理器追蹤到很少的幾個(gè)BUG,一系列叫內(nèi)存調(diào)試器的工具誕生了。最總所周知的是Purify,在1991年被Pure軟件公司發(fā)布。Purify一直被用于一些同類的內(nèi)存調(diào)試器。也有Insure++,Valgrind,也有BoundsChecker,除此之外的一些其他同類工具。 內(nèi)存調(diào)試器作用于所有被動(dòng)態(tài)分配的內(nèi)存。他們同樣攔截和檢查分配過的內(nèi)存。一些內(nèi)存調(diào)試器能夠檢查一些被分配在棧上的局部變量和被分配過的內(nèi)存。Purify和BoundsC
38、hecker用代碼編譯工具完成這些工作在程序連接期間,Insure++利用源代碼編譯工具,Valgrind則把程序先執(zhí)行在虛擬機(jī)上并且監(jiān)聽所有的內(nèi)存處理。源代碼編譯工具允許一個(gè)BUG發(fā)生的時(shí)候精確的找到代碼發(fā)生的位置。 一下的BUG被內(nèi)存調(diào)試器處理: 1. 內(nèi)存泄漏 2. 訪問已經(jīng)被釋放的內(nèi)存 3. 釋放一段內(nèi)存空間不止一次 4. 釋放從未被分配過的內(nèi)存 5. 把C中的malloc(),free()與C++中的 new/delette混雜在一起 6. 在數(shù)組中用delete代替delete[] 7. 數(shù)組越界錯(cuò)誤 8. 訪問從未被分配過的內(nèi)存 9. 未被定義過的內(nèi)存讀取
39、10. 空指針讀或?qū)? 我們將在下一章節(jié)演示如何為你的程序附屬內(nèi)存調(diào)試器,內(nèi)存調(diào)試器如何發(fā)現(xiàn)和報(bào)告錯(cuò)誤。 4.3 例1檢測(cè)內(nèi)存訪問錯(cuò)誤 我們第一個(gè)例子是在動(dòng)態(tài)內(nèi)存中分配一列,存取最后一個(gè)在數(shù)組序列外的元素,讀一個(gè)未定義的數(shù)組元素,最終忘記分配這個(gè)數(shù)組。我們用公共范圍工具Valgrind在Linux上作為內(nèi)存調(diào)試器,演示內(nèi)存調(diào)試器如何自動(dòng)的解決這些BUG。 4.3.1 檢查一個(gè)無用的寫操作 第一個(gè)最大最嚴(yán)重的錯(cuò)誤是緩存溢出:對(duì)這個(gè)數(shù)組以外的寫操作。因?yàn)檫@個(gè)數(shù)組只有100個(gè)元素,最大的有效索引是99。100指針超過了這個(gè)數(shù)組的有效范圍。一次報(bào)告一個(gè)無用的寫錯(cuò)誤。 ==11323== In
40、valid write of size 4 ==11323== at 0x8048518: main (main1.c:9) ==11323== Address 0x1BB261B8 is 0 bytes after a block ==11323== of size 400 alloc’d ==11323== at 0x1B903F40: malloc ==11323== (in /usr/lib/valgrind/vgpreload_memcheck.so) ==11323== by 0x80484F2: main (main1.c:6) 這個(gè)字符串,應(yīng)用一個(gè)過程ID,當(dāng)Va
41、lgrind檢查過程的時(shí)候是十分必要的。最重要的信息塊是在第9行的寫操作。這依然有信息補(bǔ)充說明根據(jù)以離內(nèi)存最近的區(qū)域和它是怎么被分配的。內(nèi)存調(diào)試器猜測(cè)第9行與內(nèi)存阻塞有關(guān)。這個(gè)猜測(cè)被修正因?yàn)閮蓚€(gè)都屬于數(shù)組A。 在Valgrind中內(nèi)存中數(shù)組下標(biāo)越界錯(cuò)誤只有當(dāng)動(dòng)態(tài)內(nèi)存被定義為malloc()或new的情況下。這個(gè)是第6行的實(shí)例: 6 int*A = (int * )malloc (sizeof(int) * size) 如果例子中書寫A[size]在第6行,A將被定義在一個(gè)局部變量上,堆而不是棧上。它表現(xiàn)出Valgrind不能夠發(fā)現(xiàn)這樣的錯(cuò)誤但是Purity可以捕獲到它們。它說明不是所有的內(nèi)存調(diào)試器都能捕獲到同一個(gè)錯(cuò)誤。
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025《增值稅法》高質(zhì)量發(fā)展的增值稅制度規(guī)范增值稅的征收和繳納
- 深入學(xué)習(xí)《中華人民共和國(guó)科學(xué)技術(shù)普及法》推進(jìn)實(shí)現(xiàn)高水平科技自立自強(qiáng)推動(dòng)經(jīng)濟(jì)發(fā)展和社會(huì)進(jìn)步
- 激揚(yáng)正氣淬煉本色踐行使命廉潔從政黨課
- 加強(qiáng)廉潔文化建設(shè)夯實(shí)廉政思想根基培育風(fēng)清氣正的政治生態(tài)
- 深入學(xué)習(xí)2024《突發(fā)事件應(yīng)對(duì)法》全文提高突發(fā)事件預(yù)防和應(yīng)對(duì)能力規(guī)范突發(fā)事件應(yīng)對(duì)活動(dòng)保護(hù)人民生命財(cái)產(chǎn)安全
- 2023年四年級(jí)數(shù)學(xué)上冊(cè)第一輪單元滾動(dòng)復(fù)習(xí)第10天平行四邊形和梯形作業(yè)課件新人教版
- 2023年四年級(jí)數(shù)學(xué)上冊(cè)第14單元階段性綜合復(fù)習(xí)作業(yè)課件新人教版
- 2023年四年級(jí)數(shù)學(xué)上冊(cè)易錯(cuò)清單十五課件新人教版
- 2023年四年級(jí)數(shù)學(xué)上冊(cè)易錯(cuò)清單七課件西師大版
- 2023年五年級(jí)數(shù)學(xué)下冊(cè)易錯(cuò)清單六作業(yè)課件北師大版
- 2023年五年級(jí)數(shù)學(xué)下冊(cè)易錯(cuò)清單二作業(yè)課件北師大版
- 2023年五年級(jí)數(shù)學(xué)下冊(cè)四分?jǐn)?shù)的意義和性質(zhì)第10課時(shí)異分母分?jǐn)?shù)的大小比較作業(yè)課件蘇教版
- 2023年五年級(jí)數(shù)學(xué)下冊(cè)周周練四作業(yè)課件北師大版
- 2023年五年級(jí)數(shù)學(xué)下冊(cè)六折線統(tǒng)計(jì)圖單元復(fù)習(xí)卡作業(yè)課件西師大版
- 2023年四年級(jí)數(shù)學(xué)上冊(cè)6除數(shù)是兩位數(shù)的除法單元易錯(cuò)集錦一作業(yè)課件新人教版