Tutorial 1 - Creating a C/C++ KAST checkerTutorial 1 - Creating a C/C++ KAST checkerThis tutorial describes how to create a simple C/C++ KAST checker. Run kwcreatecheckerMove to the directory where you want the checker files to be created, and from the VS prompt if you're in Windows, run kwcreatechecker with the following options: kwcreatechecker --language cxx --type kast --code MY.C.KAST.CHECKER The --code option specifies the name we're assigning to the checker. Note: Multibyte characters are not supported in error IDs (checker names), and there's a 255-character limit.
A directory is created with the name you specified with --code . This directory contains the checker stub files. In the case of the example above, the directory is named MY.C.KAST.CHECKER. The MY.C.KAST.CHECKER directory contains:
Create the simplest test caseThe first test case for the checker should be as simple as possible. As you develop the checker, you can add and test more complex cases. The checker we're going to create in this tutorial detects variable assignment in an if statement. It is easy to mis-type the equal operator a == b as the assignment operator a = b (single equal sign instead of double equal sign), which still results in valid C/C++ code. The simplest code fragment that will generate this Klocwork error is: void f(int a, int b) { if (a = b) { //Error: assignment of b to a in if statement /* do stuff */ } } Replace the template code in the testcase.cc file with this code MY.C.KAST.CHECKER/testcase.cc). Use Checker Studio to find KAST nodes of interestNow that you have a simple test case, the next step is to open Checker Studio.
Draft the KAST expressionThe nodes you identified in the previous step are: IfStmt, Cond, and BinaryExpr. Put this together into the KAST expression to produce: //IfStmt / Cond::BinaryExpr [ @Op = KTC_OPCODE_ASSIGN ] Note that KAST provides a built-in function that returns the value of the Op attribute for an expression node: getOperationCode(). We will use this function in this tutorial in place of explicitly querying a particular attribute, leading us to the following KAST statement: //IfStmt / Cond::BinaryExpr [ getOperationCode() = KTC_OPCODE_ASSIGN ] This KAST expression will search the AST for if statements that contain an assignment in the condition statement. (For detailed information about the elements of KAST expressions, see C/C++ KAST syntax reference.) Now that we have a KAST expression, our next step is testing the expression. Test the KAST expression
Add more complexity to the test caseThe next step in the KAST checker development process is to add more tests to the test case. Tests to add can be:
For the sample checker in this tutorial, we'll add three more false-positive test cases:
These cases should not generate a Klocwork error. 1. Change the code in testcase.cc to: void f(int a, int b) { if (a = b) { /* ERROR - assignment in condition */ } if (a > b) { /* OK - no assignment */ } if (a == b) { /* OK - equal check, not assignment */ } if ((c = getchar()) != EOF) { /* OK - assignment as part of more complex expression */ } } 2. Paste the new code into Checker Studio, and run the test again. The results indicate that no false positives were generated (all the test cases were covered). Add the KAST expression to the checkers.xml fileNow that the checker's KAST expression is complete and tested, we can add it to the checkers.xml file, which is generated by running kwcreatechecker. When this file is first generated, its values are automatically populated with an error ID, severity, message, and title, as well as a sample KAST expression, so that it's obvious what you have to change to define your own checker. In this particular case, we are interested in the pattern element of this XML file, and will modify it as follows: <pattern> // IfStmt / Cond::BinaryExpr [ getOperationCode() = KTC_OPCODE_ASSIGN ] </pattern>
Create help for your checkerChecker documentation can be added by editing the help.xml file, which is bundled with the other checker files when you first create the checker. At minimum, you should provide a useful description for your checker, but you may also find it valuable to provide content for the other sections, such as risks, in which you could describe how a typical mistake that this checker detects could lead to exposure, or prevention, in which you could explain how to address that exposure via code fixes. When the checker is deployed, any help content you provide will be integrated automatically with the online help collection. Build the checkerNow that we've added the checker's KAST expression to the checkers.xml file and created help, it's time to build the checker. To make this simple, kwcreatechecker adds a Makefile to the checker directory when first run. Under Unix or OS/X (or anything else non-Windows), run: make install buildspec Under Windows, make sure that you're using a Visual Studio command prompt, and run: nmake install buildspec This generates:
Test the checkerWhile you're still testing, it's best to deploy the checker to your desktop, rather than the server project.
What's next?Try writing a checker with more built-in functions. |