
Practical Memory Checking with Dr. Memory Derek Bruening Qin Zhao Google Massachusetts Institute of Technology [email protected] qin [email protected] Abstract—Memory corruption, reading uninitialized memory, tools because of the heavyweight monitoring required to detect using freed memory, and other memory-related errors are among memory errors. Application heap and stack allocations must the most difficult programming bugs to identify and fix due to be tracked, and each memory access by the application must the delay and non-determinism linking the error to an observable symptom. Dedicated memory checking tools are invaluable for be checked by the tool, incurring significant overhead. finding these errors. However, such tools are difficult to build, Accuracy is another challenge: valid memory operations that and because they must monitor all memory accesses by the appear to violate memory usage rules are not uncommon in application, they incur significant overhead. Accuracy is another system libraries and other locations out of control of the tool challenge: memory errors are not always straightforward to user, and false positives must be avoided while still detecting identify, and numerous false positive error reports can make a tool unusable. A third obstacle to creating such a tool is that it real errors. The largest class of false positives are uninitialized depends on low-level operating system and architectural details, read errors stemming from copying whole words containing making it difficult to port to other platforms and difficult to valid sub-word data (discussed in Section II-A); avoiding target proprietary systems like Windows. these false positives requires monitoring not only memory This paper presents Dr. Memory, a memory checking tool that accesses but nearly every single application instruction, further operates on both Windows and Linux applications. Dr. Memory handles the complex and not fully documented Windows envi- decreasing performance. Accuracy is also an issue for leak ronment, and avoids reporting false positive memory leaks that checking. To detect leaks, most tools perform a garbage- plague traditional leak locating algorithms. Dr. Memory employs collection-style scan at application exit to identify unreach- efficient instrumentation techniques; a direct comparison with the able heap allocations. However, without semantic information state-of-the-art Valgrind Memcheck tool reveals that Dr. Memory assumptions must be made and can lead to false positives. is twice as fast as Memcheck on average and up to four times faster on individual benchmarks. A third challenge in creating memory checking tools is their Index Terms—Memory Checking, Shadow Memory, Dynamic dependence on low-level operating system and architectural Optimization details. Notably, the most popular non-commercial tool, Mem- check, remains a UNIX-only tool despite widespread demand I. INTRODUCTION for a Windows port. Since these tools typically operate in Memory-related errors are among the most problematic pro- user mode, memory references made by the operating system gramming bugs. These errors include use of memory after free- cannot be directly monitored by the tool. Instead, each system ing it, reads of uninitialized memory, memory corruption, and call’s effects on application memory must be emulated. This memory leaks. Observable symptoms resulting from memory requires detailed knowledge of each parameter to each system bugs are often delayed and non-deterministic, making these call, which is not easy to obtain for proprietary systems errors difficult to discover during regular testing. Strategies like Windows. Additionally, the Windows programming en- for detecting memory bugs usually rely on randomly encoun- vironment contains multiple heap libraries, some relatively tering visible symptoms during regular application execution. complex, which complicate heap monitoring. Furthermore, the sources of these bugs are painful and time- This paper presents Dr. Memory, a memory checking tool consuming to discover from observed crashes that occur much with novel solutions to the challenges listed above. Im- later than the initial memory error. For all of these reasons, proving on each of these issues makes for a more prac- memory bugs often remain in shipped products and can show tical tool. Dr. Memory is open-source and available at up in customer usage. Dedicated memory checking tools are http://code.google.com/p/drmemory/. needed to systematically find memory-related errors. B. Contributions A. Memory Checking Tools Memory checking tools in use today include Valgrind This paper’s contributions include: Memcheck [16], Purify [7], Intel Parallel Inspector [9], and • We describe the design for a complete memory checking Insure++ [15]. Such tools identify references to freed memory, tool that supports both Windows and Linux. array bounds overflows, reads of uninitialized memory, invalid • We enumerate possible function wrapping approaches calls to heap routines such as double frees, and memory leaks. and present a wrapping technique that is transparent and These tools are large, complex systems that are difficult to handles mutual recursion, tailcalls, and layered functions. build and perfect. • We present a novel technique for identifying and delim- There are three major challenges in building a memory iting stack usage within heap memory. checking tool. Performance is a serious challenge for these • We categorize the sources of false positives in Shadow Memory Shadow Stack Shadow Heap Stack Heap application). Unless the sub-word variable is explicitly packed defined header unaddr into a struct by the programmer, the additional bytes will uninit defined simply be uninitialized padding bytes. If a tool reports any read uninit of an uninitialized byte as an error, most applications would defined malloc defined exhibit numerous false positives, making such a tool more difficult to use as true errors are drowned out by false errors. unaddr padding unaddr To eliminate these false positives, instead of using shadow header unaddr metadata that is permanently associated with its corresponding freed unaddr application memory location, we dynamically propagate the shadow values to mirror the application data flow and only Fig. 1. Example of shadow memory corresponding to application memory report errors on significant reads that affect program behavior, within the application stack and heap. such as comparisons for conditional jumps or passing data to 1 Confidential a system call. This requires that we shadow not only memory but registers as well. Our implementation propagates shadow reachability-based leak detection and present novel tech- values through general-purpose registers but not floating-point niques for avoiding them. or multimedia registers as the latter rarely if ever exhibit the • We present an encoding for callstacks that significantly sub-word problem. reduces memory consumption. Table I summarizes how Dr. Memory maintains the shadow • We describe a series of instrumentation techniques and metadata and when it checks for errors. For example, Dr. optimizations that improve on the performance of the Memory intercepts calls to library routines that allocate mem- state-of-the-art memory checking tool, Memcheck, by an ory, such as malloc and HeapAlloc, and performs two average of 2x and by up to 4x on individual benchmarks. actions: adjusting the size of the allocation to add redzones C. Outline (see Section IV-A) and updating the shadow memory to Section II presents the overall design of our memory check- indicate that the requested allocation is valid to access. Ex- ing tool and our method of inserting instrumentation into isting memory checking tools, including Memcheck, follow the running application. Section III shows how we achieve similar courses of action, though some tools do not propagate good performance with our inserted instrumentation. Next, shadow values and suffer from the sub-word false positives Section IV discusses wrapping heap library functions, fol- described above. Propagating shadow metadata requires taking lowed by handling kernel interactions in Section V. Section VI action on nearly every single application instruction. When describes our leak detection scheme. Experimental results with combining two shadow values during propagation (e.g., two Dr. Memory are presented in Section VII. source operands to an arithmetic instruction), the general rule is that undefined combined with defined results in undefined. II. SYSTEM OVERVIEW We encode our shadow values such that we can use a bitwise Dr. Memory uses memory shadowing to track properties or to compute this operation. of a target application’s data during execution. Every byte of B. Instrumentation System application memory is shadowed with metadata that indicates one of three states: Dr. Memory is built on the open-source DynamoRIO [4] dynamic instrumentation platform, which provides Dr. Mem- • unaddressable: memory that is not valid for the applica- ory with the necessary monitoring capabilities. DynamoRIO tion to access. uses a software code cache to support inserting arbitrary • uninitialized: memory that is addressable but has not been instrumentation that is executed interleaved with copies of the written since it was allocated and should not be read. original application instructions (Figure 2). • defined: memory that is addressable and has been written. Our notion of addressability is more strict than that provided III. EFFICIENT IMPLEMENTATION by the underlying
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages11 Page
-
File Size-