HP Code Advisor Version C.02.
© Copyright 2009 Hewlett-Packard Development Company L.P. Confidential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendor's standard commercial license. The information contained herein is subject to change without notice.
Table of Contents About This Document.........................................................................................................9 Intended Audience.................................................................................................................................9 Document conventions and symbols......................................................................................................9 Related Information.................................................................
5.7 Disabling Warnings in a Macro.......................................................................................................34 5.8 Managing Warnings in a Source File...............................................................................................35 6 Generating Reports......................................................................................................37 6.1 Report Generation Options Table............................................................................
List of Figures 1-1 2-1 Cadvise Components (User Interfaces).........................................................................................11 Steps in Using Cadvise..................................................................................................................
List of Tables 1 2-1 4-1 6 Document conventions....................................................................................................................9 Source structure in the rules library..............................................................................................23 Cross-file analysis options.............................................................................................................
List of Examples 2-1 2-2 2-3 2-4 2-5 3-1 3-2 3-3 3-4 3-5 4-1 4-2 4-3 4-4 4-5 5-1 5-2 5-3 5-4 5-5 5-6 5-7 6-1 6-2 6-3 6-4 6-5 6-6 6-7 6-8 6-9 6-10 6-11 6-12 6-13 6-14 6-15 6-16 6-17 6-18 6-19 6-20 6-21 7-1 7-2 7-3 7-4 7-5 7-6 7-7 Updating the makefile to integrate cadvise..................................................................................17 Sample wrapper script..................................................................................................................
-1 8-2 8-3 8-4 8-5 8-6 8-7 8-8 8-9 8-10 8-11 8-12 8 Null pointer dereference check.....................................................................................................57 Potential memory leak check.........................................................................................................58 Out of bound access......................................................................................................................59 Out of scope access.............................
About This Document This document discusses the invocation and usage of HP Code Advisor. Intended Audience This document is intended for programmers who want to detect the potential errors or warnings in C, C++ applications by using HP Code Advisor. Document conventions and symbols Table 1 “Document conventions” lists the conventions and symbols used in this white paper.
HP Encourages Your Comments HP encourages your comments concerning this document. We are committed to providing documentation that meets your needs. Send any errors found, suggestions for improvement, or compliments to: cadvise-help@lists.hp.
1 Introduction HP Code Advisor (cadvise) is a static analysis tool for C and C++ programs. Cadvise reports various programming errors in the source code. This tool enables programmers to identify potential coding errors, porting issues, and security vulnerabilities. Cadvise leverages the advanced analysis capabilities of HP C and HP aC++ compilers available on the HP Integrity systems. This chapter addresses the following topics: • • “Cadvise User Interface” (page 11) “Features” (page 11) 1.
• • “Detection of Pre-defined or User-defined Coding Guideline Violation” (page 12) “Easy to Integrate and Use” (page 12) 1.2.1 Advanced Static Code Analysis Cadvise is a powerful static code analysis tool that automatically diagnoses various issues in a source program. It improves developer productivity by finding defects at code development time, and leads to more robust and secure software because of fewer escaped defects. Cadvise leverages advanced cross-file analysis technology from HP compilers.
You can also specify the program database and other options at the command line, as in the following example: $ cadvise -pdb ./mypdb +wlint aCC hello.cpp 1.2.7 Supported Compilers Cadvise is shipped and supported with the HP aC++ and HP C compilers on the latest HP Integrity and PA-RISC HP-UX platforms. Cadvise can also be used with GNU gcc and g++ compilers, however it does not support all gcc/g++ built-ins and extensions.
2 Using Cadvise This chapter addresses the following topics: • • • • • • • • “Getting Started” (page 15) “Steps in Using Cadvise” (page 15) “Invoking Cadvise” (page 16) “Using Cadvise as a Wrapper around Compiler or Linker” (page 17) “Integrating Cadvise with the Makefiles and Build Process” (page 17) “Enabling Different Categories of Diagnostic Messages” (page 18) “Generating Code Complexity Metrics” (page 18) “Detecting Violation of Pre-defined or User-defined Coding Guidelines” (page 22) 2.
Figure 2-1 Steps in Using Cadvise To use cadvise, you perform the following steps: 1. 2. 3. 4. 5. Build the application with the set of compiler or linker options. Ensure that the application builds successfully. Run cadvise with desired options and create the PDB. Use the reporting utility for generated reports from the PDB in various formats. Make suggested changes based on generated reports.
The cadvise command has the following modes of operation: • Analysis mode Used to analyze and create the Program Database (PDB). To invoke cadvise in this mode, enter the cadvise command in the following format: cadvise [cadvise-options] compile-cmd [compile-options] • Report mode Used to create reports.
Example 2-2 Sample wrapper script $ cat cadvise_cc #!/bin/sh # # wrapper script to invoke cadvise # exec /opt/cadvise/bin/cadvise -pdb mypdb +wlint /opt/ansic/bin/cc "$@" Now cadvise_cc can be used instead of cc in the build line to invoke cadvise analysis in addition to the compilation process. NOTE: You need not create separate dependency rules for cadvise in the makefiles. Cadvise must be invoked only when the existing dependency rules in the makefile lead to a compile.
Example 2-3 Generating code complexity metrics To store the code complexity metrics in the PDB with Indirect Call Targets, use the following command. $cadvise +metrics=ict -pdb test.pdb aCC -c example.c To get the metrics in the my.metrics file, use the following command. $cadvise +metrics :out=my.metrics aCC -c example.c To store the metrics in the my.metrics file without Indirect Call Targets, use the following command. $cadvise +metrics :out=pdb -pdb test.pdb aCC -c example.
— — — — — — — — — — Number of direct calls Targets of direct calls Cyclomatic complexity Cyclomatic complexity without switch Cyclomatic complexity without exception handling Cyclomatic complexity without switch and exception handling Number of Thread Local Storage (TLS) variables Number of mutexes Number of lock calls Number of unlock calls For each indirect call site, cadvise emits the list of possible call targets.
Example 2-4 Code complexity metrics $ cat /tmp/example.c #include #include
No. of Macros Used: 3 No. of Locals: 3 No. of Statics: 0 No. of Ifs: 0 No. of Returns: 1 No. of Loops: 1 Loop Nesting Levels: 3 No. of Indirect Calls: 0 No. of Direct Calls: 1 Functions called: print_output() Cyclomatic Complexity: 4 Cyclomatic complexity without switches: 4 Cyclomatic complexity without eh: 4 Cyclomatic complexity without switches and eh: 4 No. of Thread Local Variables: 0 No. of Mutexes: 0 No. of Lock Calls: 0 No.
Table 2-1 Source structure in the rules library include/ • HPCodeGuideConstructs.h Contains the APIs required for (re)writing the rules to enforce coding guidelines. • HPCodeGuideDiagnosticTags.h Contains the various diagnostic tags that you can use to emit the diagnostics from the rules library. lib/ • libcodeguide.a This is provided to fill in the implementation stubs for recompilation of the rules' library, and must be linked in while compiling the rules' library. • librules.
3 Using the Program Database (PDB) The PDB is a repository of errors, warnings, diagnostic messages, and metrics generated while analyzing the application. The HP Code Advisor uses the PDB also to store the information required for the analysis. If you want to perform cross-file analysis of the application, you need to use a PDB.
3.1 PDB Options Table The following options help you manage the PDB: -pdb location Enables you to specify the location (path) of the PDB. -pdb_destroy Removes the PDB specified with the –pdb option. -pdb_no_locking Do not use locks in PDB operations. -remove Removes from the PDB any information related to the specified object files. -snapshot location Creates a snapshot of the PDB at the specified location (path). -pdb_version Prints the PDB version and checks for compatibility 3.
3.5 Removing Object File Information from the PDB The -remove option removes from the PDB, any information such as logs, internal representation, and metrics related to the specified object files. Following is the syntax for removing information from the PDB: $cadvise -pdb -remove:objs/ Following is an example to remove object file information from the PDB: Example 3-3 Removing object file information from the PDB $cadvise /opt/aCC/bin/caCC foo.c -c -o objs/foo.
4 Using Cross-File Analysis Cadvise provides different operating modes for performing cross-file analysis of the application. The cross-file analysis can be performed along with the regular build of the application, or separated from the regular build. You can also initiate it either on all the files or only on a selected group of files or modules. It can also be disabled completely. The default and recommended mode is to enable cross-file analysis at link time.
Example 4-1 Using cross-file analysis automatically during linking -crossfile=auto The default cross-file option is -crossfile=auto. The cross-file analysis occurs automatically when you invoke cadvise during linking. $cadvise –pdb testpdb cc a.c b.c –c $cadvise –pdb testpdb cc a.o b.o –o test.
NOTE: The combined use of the –crossfile=defer and –crossfile=[pdb|module|list|listfile] options are useful in the following situations: • If you want to perform cross-file analysis on a set of object files that is bigger than the set of object files linked during the application build process, for example, if the application build creates multiple shared libraries, the default automatic cross-file analysis is done only across the files specified for each shared-library link command.
5 Configuring Diagnostic Messages You may want to limit the cadvise diagnostic messages depending on the need, such as the following cases: • • • Generate all possible messages to ensure that you get the maximum information about potential problems detected by cadvise. Reduce the number of messages so that you are not overwhelmed by the sheer magnitude of the warnings. Eliminate or reduce the number of benign or misleading messages.
Following is an example for emitting diagnostics from a specific file. Example 5-2 Emitting diagnostics from a specific file $cadvise report -pdb test.pdb –summary -include file1.c 5.4 Suppressing Warnings Selectively The +Warg1[,arg2,...,argn] option selectively suppresses any specified warning messages. NOTE: arg1 through argn must be valid warning message numbers. Following is the syntax for selectively suppressing warnings. $cadvise +wall -pdb +Warg1[,arg2,...
NOTE: Conflicts between +W, +Ww and +We options are resolved based on the severity. The +We option is the highest and +W is the lowest. Following is the syntax for disabling warnings in a macro. $cadvise +wall -pdb +Wmacro:INITIAL:d1,d2,d3,..dn compile-cmd Following is an example for disabling warnings in a macro. Example 5-6 Disabling warnings in a macro $cadvise +wall -pdb testpdb +Wmacro:INITIAL:600,610 cc -c foo.c 5.
6 Generating Reports Cadvise either stores the diagnostic messages in the PDB or outputs them into the stderr. To analyze these diagnostic messages you can generate a report using the cadvise report command. Cadvise report provides multiple options for filtering the diagnostic messages stored in the log files. These reports can also be viewed and saved as HTML files. Using these options, you can view a selected set of diagnostic messages.
Example 6-1 Generating summary reports $cadvise report -summary -pdb testpdb -noheader =============================== SUMMARY REPORT ================================= Unique warnings: 2 Duplicate warnings: 0 Sev.
default web browser (/opt/mozilla/mozilla). You can also save the generated HTML reports. • To save reports, run the following command: NOTE: This command saves the html report in a specified directory. The web browser is not invoked with this option.
... ... Following example shows the command to generate XML report. Example 6-4 Generating an XML report $ cadvise report -pdb testpdb +metrics -xml=metricsreport.xml 6.7 Printing Diagnostics with Specific Diagnostic Number(s) Each distinct type of diagnostic message generated by cadvise has a number associated with it. The -diag N1,N2,N3,...,Nn option prints only those diagnostics with the specified diagnostic number(s).
Example 6-6 Generating reports based on severity $ cadvise report -pdb test.pdb –all –severity 2. This command prints all diagnostics of severity levels greater than or equal to two. 6.9 Suppressing Diagnostics for Specific File(s) The -exclude option helps to eliminate diagnostics for files that contain any of the strings from 1 to n in the file. NOTE: You can use the -exclude option along with other filtering options, such as -diag, -include, and -severity.
Example 6-8 Reporting diagnostics from specific file(s). $ cadvise report -pdb test.pdb -summary -include "inflate.c" report: warning: Filtering options do not affect -summary and -file_summary Report generated using "HP Code Advisor C.XX.XX [Release Time]" on at Report command line: " cadvise report -pdb test.pdb -summary -include "inflate.c " =============================== SUMMARY REPORT ================================= Unique warnings: 257 Duplicate warnings: 0 Sev.
Example 6-9 Reporting progam complexity metrics $ cadvise report -pdb gzip.pdb +metrics -include "inflate.c" ================================================================================ Begin program complexity data for /vws/cal-bear_2/zhang/gzip-1.2.4a/inflate.
Example 6-10 Generating report for a module $ cadvise report -pdb test.pdb -summary -module test1 =============================== SUMMARY REPORT ================================= Report generated using "HP Code Advisor C.XX.XX [Release Time]" on at Report command line: " cadvise report -pdb test.pdb -summary -module test1" Unique warnings:29 Duplicate warnings: 0 Sev.
6.15.1 Generating Summary Diff Report Using the PDB comparison option along with the -summary option displays the difference between the summary reports of 2 PDBs. The following example shows the usage of -basepdb summary difference report: Example 6-13 Generating summary diff report without the header $ cadvise report -pdb test.pdb -basepdb test0.pdb -summary -noheader Sev.
Example 6-15 Generating diff report for any particular warning $ cadvise report -pdb tmp.pdb -basepdb tmp1.pdb -diag 2549 Report generated using "HP Code Advisor C.XX.XX [Release Date]" on at
Example 6-18 Generating detailed diff report in the warnings greater than or equal to any particular severity $ cadvise report -pdb tmp.pdb -basepdb tmp1.pdb -severity 1 Report generated using "HP Code Advisor C.XX.XX [Release Date]" on at
1. 2. 3. 4. See a summary report using cadvise report. This gives an overview of the diagnostic messages that have been generated for the application. Analyze all high severity ( >= 7) diagnostic messages generated by cadvise. These diagnostic messages have a very low false positive rate and are likely to point out defects in the application. Each distinct type of diagnostic message generated by the code advisor has a number associated with it.
Example 6-21 Ignoring the -include option $ cadvise report -pdb test.pdb -summary -include "a.c:b.c" report: warning: Filtering options do not affect -summary and -file_summary Report generated using "HP Code Advisor C.XX.XX [Release Time]" on at Report command line: " cadvise report -pdb test.pdb -summary -include "a.c:b.c" =============================== SUMMARY REPORT================================== Unique warnings: 257 Duplicate warnings: 0 Sev.
7 Miscellaneous Driver Options You can also use the following cadvise options to manage the static analysis and the compilation processes: -compiler [aCC|cc|c89|c99|gcc|g++|ld] Specifies the compiler or linker command used in the command line. -help|-h|-H Displays the complete list of cadvise options with a brief description for each option. -[no]abort Determines whether to return a non-zero exit value for cadvise errors. The default is -noabort.
The syntax for determining the invocation of the compile or link command after the cadvise static analysis is as mentioned below: $ cadvise -nobuild -w The following example shows the usage of -[no]build option. Example 7-4 Using -nobuild option $ cadvise -nobuild /opt/ansic/bin/cc -w t1.c This results in the compile command line /opt/ansic/bin/cc -w t1.c not getting executed. • -target[=.ext|filename] This option creates an empty file called filename or .
Example 7-7 Using +opts option $cat warnings_config # warnings_config # change warning about use of undefined variable to an error +We2549 # enable warning about redeclaration of variable +Ww3348 # disable warning: statement is unreachable +W2111 $ cadvise +opts warnings_config +wlint cc -c uninit.c at the command line generates the following messages: "uninit.c", line 6: warning #3348-D: declaration hides variable "i" (declared at line 3) int i; ^ "uninit.
8 Categories of Diagnostics with Examples Cadvise detects a wide range of coding errors and potential problems such as memory leaks, used after free, double free, array/buffer out of bounds access, illegal pointer access, un-initialized variables, unused variables, format string checks, suspicious conversion and casts, out of range operations, and C++ coding style warnings. 8.
- Missing return statement at end of non-void function Nested comment is not allowed Signed bitfield of length 1 Potential memory leak detection Potential null pointer dereference detection Out of bound access Out of scope access Use of pointer after free Allocator/deallocator mismatch The following are some detailed examples of warnings generated by +wlint checks: 56 Categories of Diagnostics with Examples
Example 8-1 Null pointer dereference check A null pointer may result from null assignment or from a call to the APIs that may return a null value. If a pointer that is not guarded when it is dereferenced, unexpected runtime results may occur. For example, see the following program fragment: #include
Example 8-2 Potential memory leak check Cadvise detects potential memory leaks in the program where the memory allocated in the program is not freed. If a dynamically allocated memory becomes unreachable from any other pointers, then the memory is leaked after that point in the program, assuming that there is no garbage collection in the allocator. Cadvise flags such situations as shown in the following example code fragment: #include #include #include
Example 8-3 Out of bound access When an array is referenced and the index is greater than the declared (or dynamically allocated) size, unexpected runtime behavior may occur. In such cases, cadvise flags it as potential array out of bound access violation.
Example 8-5 Use of pointer after free When there is reference to a memory through a pointer that has been previously freed, cadvise detects such potential issues as Use After Free cases. For example, see the following code: void use_after_free () { char *p = malloc (20); strcpy (p, "hello"); free (p); *p = 'c'; } In such cases, cadvise generates the following error: free.
Example 8-7 Signed bit field of length 1 Cadvise warns cases where signed bit field of length 1 is being used and then assigned with a value, which is excessive of its size. For example, see the tags in the following code: $ cat bitfield.c struct { int bit:1; } s; void test() { s.bit = 1; } In such cases, cadvise generates the following warnings: "bitfield.c", line 1: warning #2108-D: signed bit field of length 1 struct { int bit:1; } s; ^ "bitfield.
Example 8-9 Detecting endian dependent code fragments Consider the following code fragment. union Endian { char c[4]; int v; }; In such cases, cadvise generates the following warning: "endian1.c", line 2: warning #4289-D: endian porting: the definition of the union may be endian dependent union Endian { ^ The +wendian option can catch various potential endian dependent data structures and usage.
Example 8-10 Enabling compile time diagnostic messages for potential security vulnerabilities #include #include char* get_path() { return getenv("BLAHBLAH"); } int main() { char* path = get_path(); // line 11 FILE* my_pipe = popen(path, "r"); // line 13 printf ("%p\n", my_pipe); } In this case, cadvise generates the following error: "popen.
Example 8-11 Detecting multi-threaded programming issues #include #include int a; pthread_mutex_t Mutex; void perform_operation(pthread_mutex_t* mutex1, int increment, int* global) { if (increment > 10) { int status = pthread_mutex_lock(mutex1); } *global = *global + increment; int status = pthread_mutex_unlock(&Mutex); } int main(void) { int i; scanf("%d", &i); perform_operation(&Mutex, i, &a); printf("%d is value\n", a); } Running cadvise generates the following error: "1.
Example 8-12 Detecting potential performance improvement opportunities bash-2.05b$ cat /tmp/example.c struct X{ int i; int arr[100]; } x; int foo( struct X); int main() { foo (x); //line 16 } $ cadvise +wperfadvice aCC -c /example.c "/example.c", line 16: warning #4319-D: performance advice: passing a large (404 bytes) parameter by value is inefficient, consider passing by reference foo (x); ^ 8.
9 Fixing the Warnings by Source Change The HP Code Advisor Diagnostics document enables you fix the warnings with a brief description for a partial list of diagnostics emitted by cadvise. In this document, there are four sections for each description as mentioned below: • The Cause section • The Example section Provides relevant sample code segments that result in the specific diagnostic.
10 Incompatibilities on PA-RISC Based Systems On PA-RISC-based systems, a few non-standard source constructs may not be accepted by cadvise. In such cases, cadvise generates an error and continues processing the next source file. For more information, see the following page: aC++ standard conformance and compatibility changes. In such cases, the best way is to modify the source code so that the code is more standards compliant and is compilable on platforms based on both Integrity and PA-RISC.
Index Symbols G +metrics, 42 +opts , 47 +opts , 52 +w, 55 +w64bit, 61 +wall, 55 +Warg1[,arg2,...,argn], 34 +Wearg1[,arg2,..,argn], 34 +wendian, 61 +wlint, 55 +wlock, 63 +Wmacro:MACRONAME:d1,d2,d3,..dn, 34 +wperfadvice[=1|2|3|4], 64 +wsecurity[=1|2|3|4], 62 +Wwarg1[,arg2,..,argn], 34 -[no]abort, 51 -all, 38 -basepdb , 44 -build, 51 -chseverity , 44 -compiler [aCC|cc|c89|c99|gcc|g++|ld], 51 -diag N1,N2,N3,...