Chapter 2. Tutorials for the Static Analyzer

This chapter shows how you might use the Static Analyzer in a typical session. It does not go into full detail, but it does explain the fundamental concepts you will need to use the Static Analyzer. It lists related commands and controls after each tutorial so you can experiment on your own.

Note that the compiler used in this tutorial is not the SGI MIPSpro compiler; the compiler examples used here are for an older version of C++ compiler.

This chapter discusses the following topics:

Applying the Static Analyzer to Scanned Files

In this session, you will create a fileset for the demo program bounce using scanner mode and perform some basic queries in text mode.

  1. Move to the /usr/demos/WorkShop/bounce directory by entering the following command:

    % cd /usr/demos/WorkShop/bounce

    This directory contains the C++ source code files for the demo program bounce.

  2. Use the ls(1) command to list the directory's contents to see if the file cvstatic.fileset already exists (in case someone worked through a tutorial and forgot to remove the file). If it does exist, remove it along with any other files the Static Analyzer may have left by entering the following command:

    % rm cvstatic.* cvdb* vista.taf

    Whenever you run the Static Analyzer, it checks the directory where you invoked it for the cvstatic.fileset file and uses the content of that file as its fileset. If it does not find the cvstatic.fileset file, it creates and saves its own fileset containing the expression *.[c|C|f|F] so that all possible C files (.c), Fortran 77 files (.f), Fortran 90 (.F), and C++ files (.C) in the current directory are included. When you quit the Static Analyzer, any fileset you or the Static Analyzer created remains in the directory for use in your next Static Analyzer session.

    If you do not want to use the default fileset, you can create your own or modify the default fileset using the Edit Fileset selection on the Admin menu. You can also create your own cvstatic.fileset file by hand; instructions are found in “Creating a Fileset Manually ” in Chapter 3.

  3. Start the Static Analyzer by entering the following command:

    % cvstatic &

    The Static Analyzer window appears (as shown in Figure 2-1).

    Figure 2-1. The Static Analyzer Window

    The Static Analyzer
Window

  4. Choose Edit Fileset from the Admin menu to open the Fileset Editor window (as shown in Figure 2-2).

    Figure 2-2. The Fileset Editor Window

    The Fileset Editor
Window

    The current working directory appears in the Browsing Directory field at the top left of the window. Subdirectories (if any) appear in the Directories field. The files in the current working directory appear in the Files field. Select the files you want to include in the fileset from these two lists. For parser mode files, click the associated Parser button. For scanner mode, click the Scanner button. There are two sets of Parser and Scanner mode buttons. The upper set moves whole directories and the lower set moves individual files. The two fileset fields, Parser Fileset and Scanner Fileset, are at the right of the window.

  5. Select the expression *.[c|C|f|F] in both the Parser Fileset and Scanner Fileset list fields (if it appears), and click the Remove button.

    This removes any default expressions from the fileset.

  6. Click the C++ language filter button.

    This filters the Files list to include only those files with the .C extension (signifying C++ source files) and selects them all.

  7. Now add these source code files to the fileset by clicking the Scanner button from the Move Files set of buttons.

    The Scanner Fileset list now displays the files selected from the Files list. These files will be scanned into the static analysis database when it is created.

  8. Click the OK button at the bottom of the Fileset Editor window.

    After you have created the fileset, you can query it for useful information. Your first query prompts the Static Analyzer to extract static analysis data from the files in the fileset and create a cross-reference database (using scanner mode). This occurs before returning the results of your query. The database includes the relationships between functions, files, classes, and other elements of the code in the fileset, and is saved in a database file along with two accompanying index files. The database file is named cvstatic.xref; the accompanying files are named cvstatic.index and cvstatic.posting. These files are stored in the same directory as the fileset with which they are associated and remain there after the Static Analyzer quits.

    Subsequent queries use the same database until you ask the Static Analyzer to rescan the fileset, which creates an updated database. When you quit the Static Analyzer and return to it later, it automatically updates the database, going through any files in the fileset that have changed since the last session. If you use appropriate wild card expressions in the fileset, the fileset will automatically accommodate new files added to specified directories.

  9. From a shell, list the contents of the cvstatic.fileset file.

    All files and their paths to be included in the fileset should display. If you selected files for parsing, the files will have compiler flags following their path names.

  10. Click the Queries menu to open it.

    To query the database, choose a command from the Queries menu. You'll find the commands grouped in submenus according to the type of query (see Figure 2-3).

    Figure 2-3. Static Analyzer Queries Menu and Query Target Field

    Static Analyzer Queries
 Menu and Query Target Field

    The Query submenus let you perform the following types of different searches:

    • The General submenu searches for text strings, regular expressions, and symbols.

    • The Macros submenu searches for locations of macro definitions and places where macros are used.

    • The Variables submenu searches for global and local variables and shows where they are defined and who references and sets the variables.

    • The Functions submenu searches for functions, shows where they are defined, and shows who calls them and whom they in turn call.

    • The Files submenu searches for files in the fileset (including headers and libraries) and shows which files are included by which other files.

    • The Classes submenu searches C and C++ files for classes and shows where they are defined. It also shows subclass and superclass relationships and lists the methods defined within classes.

    • The Methods submenu searches C/C++ files for methods and shows where they are defined and declared.

    • The Common Blocks submenu searches Fortran 77 and Fortran 90 files for common blocks.

    • The Types submenu searches C and C++ files for type information.

    • The Directories submenu lets you list directories or the files in a directory.

    To start a query, choose the type of query you want from the Queries menu. The Static Analyzer searches through its database or through the original source code to find what you asked for.

    If you want to look for a specific function, file, string, or other element, enter the target text in the Query Target field above the query results area (as shown in Figure 2-1).

    Queries that require text in the Query Target field (such as Find String in the General submenu) are grayed in the Queries menu if there is no text present. More general queries that require no search text (such as List Global Symbols) are always available.

  11. Choose the List All Functions selection from the Functions submenu of the Queries menu.

    The Static Analyzer builds its cross-reference database and notifies you that it is doing so. When it is finished, the Static Analyzer displays a list of all functions found in the fileset (as shown in Figure 2-4), their file, the line number at which they are first defined or declared, with the actual source line.


    Note: During this process, you may get a warning dialog box about multiple function occurrences. This is due to the inaccuracy of scanner mode; it has problems with #ifdef statements. You may also get an error message about missing files. This can happen if your include paths are not set correctly. The missing files are not necessary for this tutorial.


    Figure 2-4. The Results of a List Functions Query

    The Results of a List Functions
Query

    The Static Analyzer returns the results of all queries in the query results area (below the Query Target field). It presents this information in text form (and by the previous type of view if applicable for subsequent queries). You can scroll through a text list to find specific data that interests you. Clicking any part of an element listed (a filename, a function name, a line number, and so on) pastes it into the Query Target field so you can use it as the base of your next search. For example, if you want to determine what functions a particular function calls, click on the function name to put it into the Query Target field and then choose the Who Is Called By selection from the Functions submenu of the Queries menu.

    Text view allows you to sort the element lines alphanumerically by any one of the fields in a line. For example, you can sort a list of functions alphabetically by function name or numerically by line number where they occur. To sort, click within an element line in the field by which you want to sort, and then choose Sort from the Admin menu. The Static Analyzer sorts the results of a query according to the field selected.

  12. Click the function name Actor in the query results area.

    The Static Analyzer pastes the name into the Query Target field.

  13. Choose Who Is Called By from the Functions submenu of the Queries menu.

    The Static Analyzer displays a list of all functions called by Actor.

  14. Clear the Query Target field and then type buffer in it.

    In the next steps, you are going to search for any occurrences of the text string buffer that might lead to information in the code concerning z-buffering or data buffering.

  15. Choose Find String from the General submenu of the Queries menu.

    The Static Analyzer returns all the lines of code that contain the text string buffer, even if it only appears in a comment.

  16. Click on the History menu to open it.

    It displays the queries you have made so far.

  17. Choose List All Functions from the History menu to see a list of all functions once again.

    This brings back your previous query results.

  18. Double-click the Actor function.

    The Source View window appears, displaying the source code for Actor. You can examine it, check it out (if you have a versioning system), or edit it.

  19. Choose Close from the Source View File menu to close it.

  20. Choose Exit from the Static Analyzer Admin menu to end this tutorial.

Applying the Static Analyzer to Parsed C++ Files

In this session, you will create a fileset for the bounce demo program by using parser mode and perform some detailed static analysis in both text mode and graphic mode.

  1. Move to the /usr/demos/WorkShop/bounce directory by entering the following command:

    % cd /usr/demos/WorkShop/bounce

  2. Use the ls(1) command to list the directory's contents to see if the file cvstatic.fileset already exists (in case someone worked through a tutorial and forgot to remove the file). If it does exist, remove it along with any other files the Static Analyzer may have left by entering the following command:

    % rm cvstatic.* cvdb* vista.taf

    Whenever you run the Static Analyzer, it checks the directory where you invoked it for the cvstatic.fileset file and uses the content of that file as its fileset. If it does not find the cvstatic.fileset file, it creates and saves its own fileset containing the expression *.[c|C|f|F] so that all possible, C files (.c), Fortran files (.f or .F), and C++ files (.C) in the current directory are included. When you quit the Static Analyzer, any fileset you or the Static Analyzer created remains in the directory for use in your next Static Analyzer session.

    If you do not want to use the default fileset, you can create your own or modify the default fileset using the Edit Fileset selection on the Admin menu. You can also create your own cvstatic.fileset file by hand; instructions are found in “Creating a Fileset Manually ” in Chapter 3.

  3. Start the Static Analyzer by entering the following command:

    % cvstatic -mode PARSER &

    The Static Analyzer window appears. The -mode PARSER option causes the Static Analyzer to use parser files only when queries are performed.

  4. Choose Edit Fileset from the Admin menu.

    This will allow you to use parser mode through the Fileset Editor window.

  5. Select the expression *.[c|C|f|F] in both the Parser Fileset and Scanner Fileset list fields (if it appears), and click the Remove button.

  6. Select the BouncingBall.C file in the File list at the lower left of the Fileset Editor window and click the Parser button from the Move Files set of buttons to transfer the file to the Parser Fileset list.

    This enters the BouncingBall.C file into the fileset and sets it for parsing mode.

  7. Click the OK button at the bottom of the Fileset Editor window to save the new fileset. From a shell window, enter the following command to display the contents of cvstatic.fileset:

    % cat cvstatic.fileset

    After you have created the fileset, you can query it for useful information. Your first query prompts the Static Analyzer to extract static analysis data from the files in the fileset and create a cross-reference database (using scanner mode). This occurs before returning the results of your query. The database includes the relationships between functions, files, classes, and other elements of the code in the fileset, and is saved in a database file along with two accompanying index files. The database file is named cvstatic.xref; the accompanying files are named cvstatic.index and cvstatic.posting. These files are stored in the same directory as the fileset with which they are associated and remain there after the Static Analyzer quits.

    Subsequent queries use the same database until you ask the Static Analyzer to rescan the fileset, which creates an updated database. When you quit the Static Analyzer and return to it later, it automatically updates the database, going through any files in the fileset that have changed since the last session. If you use appropriate wild card expressions in the fileset, the fileset will automatically accommodate new files added to specified directories.

  8. Choose List All Functions from the Queries Menu.

    The Static Analyzer builds a new database using parser mode. Since BouncingBall.C has a number of include files, this process may take a few minutes. During the process, a small window called Build Shell appears that displays any compiler errors or warnings. At the conclusion of the process, the functions in BouncingBall.C and its include files are listed in text form in the query results area.

  9. Choose Call Tree View from the Views menu.

    The query results area now changes to graphical form. The functions are depicted as rectangles. In addition to listing functions, the Static Analyzer now provides you with relationship information, that is, who calls which functions. The function calls are shown as arrows (or arcs) pointing to the functions that were called.

    Besides Call Tree View, there are two other types of graphical views: Class Tree View that displays C/C++ classes and their hierarchy and File Dependency View that displays files in the fileset and their dependency on each other.

    Whenever you use a tree view, the view interprets the results of your query according to the type of tree displayed. For example, if you perform a Functions query while you're in file dependency view, the view changes to show you which files contain the functions returned by the query. Some views do not make sense for displaying the results of a query, in which case the Static Analyzer switches to the view it thinks is most reasonable for the query.

  10. Click the Graph Overview button (the fourth button from the left at the bottom of the Static Analyzer window).

    This displays the Call Tree Overview window, a feature to help users navigate through a graph. It displays the full call tree in overview, with a small rectangular outline (called the viewport) in the upper-left corner. The viewport shows which portion of the tree currently appears in the query results area of the Static Analyzer window and can be dragged by the mouse to expose other portions of the graph. See Figure 2-5.

    Figure 2-5. Typical Static Analyzer Call Tree

    Typical Static Analyzer Call Tree

  11. Click in the center of the Call Tree Overview window.

    The viewport jumps so that its upper-left corner matches the pointer location. The query results area in the Static Analyzer window shifts to display the part of the tree outlined by the viewport in the Call Tree Overview window.

  12. Drag the viewport around in the Call Tree Overview window by holding down the left mouse button and moving the mouse. Finish by dragging the viewport to the upper-left corner of the call tree.

    As the viewport moves over the call tree overview, the call tree shown in the Static Analyzer query results area scrolls to match.

  13. Choose Close from the Admin menu in the Call Tree Overview window to close it.

  14. Type colorSelected in the Query Target field and choose Who Calls? from the Functions submenu in the Queries menu. This reduces the graph to three nodes.

  15. Hold the right mouse button down over the node labeled colorSelected to open its popup menu.

    This displays the individual node menu, which provides the selections: Hide Node, Collapse Subgraph, Show Immediate Children, and Show Parents. The arrow at the right of the colorSelected node indicates that it has undisplayed child nodes. Therefore, Show Immediate Children is enabled. Because the parents of colorSelected are already displayed, the Show Parents selection is disabled.

    If you hold the right mouse button down over a portion of the query results area where there are no nodes, the selected nodes menu displays providing additional selections.

  16. Choose Show Immediate Children from the popup menu.

    The Static Analyzer displays the functions called by colorSelected .

    For more information on the standard graph controls and node manipulation, see Appendix A in the ProDev WorkShop: Overview. Note that the View Options menu is unique to the Static Analyzer. It offers options that extend the range of the nodes you see in the tree to include nodes not included in the original query.

  17. Open the History menu to review the commands you have selected.

  18. Choose Exit from the Admin menu to exit the Static Analyzer.

  19. Remove all files generated by the Static Analyzer from the directory by entering the following command:

    % rm cvstatic.* cvdb* vista.taf

Using the Compiler to Create a Static Analysis Database

In this session, you will create a static analysis database by using parser mode.


Caution: The steps listed in this section will not work in all cases. You should be aware of the following limitations:

  • Using the C compiler with the -sa flag does not work for o32 programs.

  • Using the C++ compiler with the -sa flag for o32 programs may produce error messages and possibily a core dump file.

  • Templates are not supported when using the C++ compiler with the -sa flag for n32 programs.



  1. Move to the /usr/demos/WorkShop/bounce directory by entering the following command:

    % cd /usr/demos/WorkShop/bounce

    We will analyze the bounce demonstration program.

  2. Create a new subdirectory, by entering the following command:

    % mkdir staticdir

    This creates the subdirectory in which you will store the static analysis database. If a directory named staticdir already exists, remove it or use a different name.

  3. Type cd staticdir to change directories and then type initcvdb.sh.

    The initcvdb.sh script creates the cvdb*.* files necessary for producing the database.

  4. The most convenient method for applying the Static Analyzer parser to a large group of files is to modify the existing Makefile so that it analyzes the files without producing object code by entering the following command:

    -sa,staticdir -nocode

    The -sa flag tells the compiler to perform static analysis. Following -sa with ,staticdir tells the compiler to store the results in the staticdir subdirectory; otherwise, the current directory is used. The -nocode flag saves time by telling the compiler not to create object code.


    Caution: The -sa flag should be added only to a Makefile that does a sequential build. Adding the -sa flag to a Makefile that does a parallel build causes multiple copies of cc or CC to try to write to the same database. However, the database accepts only one writer at a time.


  5. Enter the following command:

    % make -k

    This runs the compiler as you have specified in the Makefile. The -k option instructs the make command to abandon work on the current entry if it fails, but to continue on other branches that do not depend on the failed entry. This may take a while. Running parser mode performs all major operations of compiling, short of creating the object code.

  6. Go to the staticdir subdirectory and enter the following command:

    % cvstatic -mode PARSER -readonly

    This invokes the Static Analyzer set for parsed files. The other mode options are SCANNER for scanned files and BOTH if you mix scanned and parsed files. The -readonly safeguard flag protects against inadvertent changes. You can now perform any valid Static Analyzer operations, as shown in the previous tutorials.

Other Static Analyzer Features

You can find complete information about querying in Chapter 4, “Queries”. To explore on your own, try these commands in the Admin menu that also affect queries:

  • Rescan: asks the Static Analyzer to update the cross-reference database by rescanning any source code files in the fileset that have changed since the last database update.

  • Force Scan: asks the Static Analyzer to update the cross-reference database by rescanning all source code files in the fileset regardless of whether they have changed.

  • General Options: offers options that determine how a query treats the text string entered in the Query Target field and how filenames are displayed.

  • Set Include Path: allows you to set a search path of directories where the Static Analyzer looks for include files that are mentioned in the code contained in the fileset.

  • Save Query: saves the text or graphics results of a query to a file. If the query results are displayed graphically, this command allows you to select a file to save the PostScript representation.


Caution: As you experiment with queries in tree views, you may be tempted to look at a coding project that includes millions of lines of code. If so, be sure to use restricted queries or to use the Results Filter to greatly filter the results of the query. If you use a very comprehensive query such as List All Functions, the Static Analyzer may be locked into creating a tree view that consists of hundreds of thousands of nodes and even more arcs. Not only will you have to wait hours for your results, but the results will probably be so complicated that they will be meaningless to you.