Developing Drivers with the Windows Driver Foundation (Pro Developer)

PREfast Best Practices

This section summarizes best practices for using PREfast and annotations.

Best Practices for Using PREfast

Consider the following general best practices for integrating PREfast into your development cycle:

Set Policies for Integrating PREfast into Your Development Practices.

Consider these ideas for integrating PREfast into your team's development practices:

Use Filtering to Analyze PREfast Results More Efficiently.

Try these guidelines for which warnings to hide:

Adopt Coding Practices that Help Reduce PREfast Noise.

Some guidelines are related to overall practices for coding and commenting:

Best Practices for Using Annotations

The following guidelines represent best practices for applying annotations:

Use Annotations in a Way that Makes Sense for Your Project.

The "right" approach to using annotations is the one that works best for your project:

Rather than postpone using PREfast until there is "time to do it right," it is better to follow a reactive model-or even to apply no annotations and ignore the noise. Typically, the time that is saved when PREfast finds even a few problems is enough to compensate for the effort of applying annotations, compared to the time that is required to debug those problems by using conventional methods. Over time, transitioning to a more proactive approach is a good idea, and the value of being more proactive should become obvious.

Use Annotations to Describe a Successful Function Call.

Annotations should reflect a successful call to the function. PREfast should catch inherently ill-formed or unsuccessful calls, not just calls that cause the system to crash. Annotations should reflect the intent of the function as reflected by its interface, not the actual implementation of the function.

A common example is optional parameters. A lot of code is written that checks to see if a parameter is NULL. But is a NULL parameter genuinely optional? For example:

If PREfast can tell the caller that a potentially NULL parameter will cause the function to fail, then PREfast can find the potential bug rather than having the bug surface at runtime in some obscure and hard-to-test-for circumstance. Having a function defend itself against bad parameters is good practice, but the fact that it does so does not make the parameter "optional" in this sense.

Consider How a Function Might Evolve.

When annotating a function, it is important to consider how the function might evolve. The annotation should reflect the intention of the function designer, not necessarily the current implementation of the function.

For example, a function as implemented might work correctly with parameter values that are different from those that the designer intended. Although it is tempting to annotate the function based upon what the code actually does, the designer might be aware of future requirements, such as the need to maintain some restriction to support some future enhancement or pending system requirement.

Resolve Conflicts between a Function and its Documentation.

Annotations can expose two kinds of "conflicts" between a function's implementation and its documentation:

Use the /W4, /WX, and /Wp64 Compiler Flags.

The compiler also detects a number of potential errors, not all of which are detected by PREfast. It is good practice to use the following compiler flags:

/W4

Warn at level 4

/WX

Make warnings fatal

/Wp64

Warn on 64-bit portability issues

Minimize the scope of any #pragma warning annotations that are used to suppress false-positive warnings from the compiler.

Use Only the Annotations Described in this Chapter for Annotating Driver Code.

Annotations are implemented in different ways, depending on the exact version of the analysis tools you are using. Documentation and header file comments that mention __declspec or annotations that use a square-bracket notation similar to those used in C# can be ignored for the purposes of using PREfast. Only the annotations that are discussed in this chapter are officially supported for annotating driver code.

 Note  Annotations can also be provided through a model file. For various reasons, many Microsoft-provided system functions are annotated in the model file and not yet annotated in the source code. The model file is no more powerful than the annotations that are described here and is more difficult to use, so its use is neither documented nor recommended for new annotations.

Some annotations are currently only partially implemented. Some annotations might be sufficient to suppress a spurious warning in PREfast, but they do not enable the additional checks that the annotation name might imply. In other cases, they are simply structured comments. These annotations are being considered for future versions of PREfast.

Категории