About Testing and Troubleshooting

Bugs related to memory access and allocation are common, but they can be difficult to find. Symptoms can range from a gradual slowing of system performance because of memory leaks to an abrupt crash if a driver attempts to access paged memory at the wrong IRQL. Crashes caused by such bugs can occur long after a driver accesses an invalid location. Corrupted memory can cause errors and crashes in processes that are completely unrelated to the offending driver.

·         Attempts to access memory that has already been freed.
·         Attempts to access beyond the end of allocated memory (memory and buffer overruns).
·         Attempts to access before the start of allocated memory (memory and buffer underruns).
·         Attempts to access paged memory at IRQL DISPATCH_LEVEL or higher.
·         Failure to free memory (memory leaks).
·         Freeing the same memory twice.
·         Failure to check the status after attempting to allocate or reference memory.

Tools for Discovering Memory-Related Errors

·         Driver Verifier
Driver Verifier has options to use the kernel special memory pool, track memory pool usage, check DMA operations, and simulate low-resource situations.

·         Global Flags (GFlags)
GFlags sets flags that enable pool tagging, provide for buffer overrun and underrun detection, and specify tags for memory allocations from the kernel special pool.

·         Call Usage Verifier (CUV)
CUV checks to ensure that data structures that must be in nonpaged memory are actually there.

·         PoolMon and PoolTag
PoolMon and PoolTag gather and display data about memory allocations. Tracking this data can help you to find memory leaks.

·         PREfast with driver-specific rules
PREfast can detect potential errors in source code by simulating execution of all possible code paths on a function-by-function basis. Errors detected by PREfast include memory and resource leaks, excessive stack use, and incorrect usage of numerous kernel-mode functions.


The best way to test your driver is to use all of these tools repeatedly, both independently and in combination. Using CUV with Driver Verifier can be particularly useful.
You should also test on various memory configurations. To change the memory configuration of the test system, you can use various boot parameters.

The /3GB switch expands user space to 3 GB, leaving only 1 GB for all kernel-mode components.
On x64 and Itanium systems, and on x86 systems that have PAE enabled and more than 5 GB of physical memory, the /nolowmem switch loads the system, drivers, and applications into memory above the 4‑GB boundary. Testing under these conditions helps you check for errors that are related to address truncation when using memory above 4 GB and inappropriate reliance on memory below 4 GB.

The /maxmem and /burnmemory switches also limit the memory available to the system by reducing the available memory by a specific amount. The /maxmem switch can be used with Windows 2000 or later versions of Windows. The /burnmemory switch is more precise and can be used with Windows XP and later versions.

Best Practices for Programming and Testing

·         Always use pool tags when allocating memory. Driver Verifier, GFlags, PoolMon, and PoolTag use these tags in tracking pool allocations, and the debuggers display a buffer’s tag along with its contents.
·         Validate the length of every buffer before accessing it.
·         Validate every user-space address by probing within an exception handler.
·         Check the returned status every time you try to allocate or access memory. Never assume that an operation cannot fail. If an error occurs, return a failure status from the driver or modify and retry the operation if appropriate. Remember: if an attempt to access memory fails because of an invalid pointer and your driver fails to catch the error when it occurs, the driver could propagate the addressing error, resulting in errors that appear much later and seem unrelated to the driver. 
·         Always use Driver Verifier.
·         Test every driver on both single-processor and multiprocessor hardware. Because Windows treats hyper-threaded processors as two CPUs, you can perform minimal multiprocessor testing on a machine with a single hyper-threaded processor. In effect, a dual-processor hyper-threaded machine provides four processors and serves as better test system. The new multicore processors would be an even better test system than the hyper-threaded systems.


For additional suggestions for testing, see “Testing for Errors in Accessing and Allocating Memory”, which is listed in the Resources section at the end of this paper.

0 komentar:

Posting Komentar

 

Serba Ada Blog Copyright © 2011-2012 | Powered by Blogger