Analyzing Program Performance With Sun WorkShop

Checking an Application

  1. Annotate your source code and compile it to create .ll files.

    See "Source Code Annotations".

  2. Load the .ll files using the load subcommand.

  3. Make assertions about locks protecting functions and variables using the assert subcommand.


    Note -

    These specifications may also be conveyed using source code annotations. See "Source Code Annotations".


  4. Make assertions about the order in which locks should be acquired in order to avoid deadlocks, using the assert order subcommand.


    Note -

    These specifications may also be conveyed using source code annotations. See "Source Code Annotations".


  5. Check that LockLint has the right idea about which functions are roots.

    If the funcs -o subcommand does not show a root function as root, use the declare root subcommand to fix it. If funcs -o shows a non-root function as root, it's likely that the function should be listed as a function target using the declare ... targets subcommand. See "declare root func" for a discussion of root functions.

  6. Describe any hierarchical lock relationships (if you have any--they are rare) using the assert rwlock subcommand.


    Note -

    These specifications may also be conveyed using source code annotations. See "Source Code Annotations".


  7. Tell LockLint to ignore any functions or variables you want to exclude from the analysis using the ignore subcommand.

    Be conservative in your use of the ignore command. Make sure you should not be using one of the source code annotations instead (for example, NO_COMPETING_THREADS_NOW).

  8. Run the analysis using the analyze subcommand.

  9. Deal with the errors.

    This may involve modifying the source using #ifdef __lock_lint (see "Limitations of LockLint") or adding source code annotations to accomplish steps 3, 4, 6, and 7 (see "Source Code Annotations").

    Restore LockLint to the state it was in before the analysis and rerun the analysis as necessary.


    Note -

    It is best to handle the errors in order. Otherwise, problems with locks not being held on entry to a function, or locks being released while not held, can cause lots of misleading messages about variables not being properly protected.


  10. Run the analysis using the analyze -v subcommand and repeat the above step.

  11. When the errors from the analyze subcommand are gone, check for variables that are not properly protected by any lock.

    Use the command: lock_lint vars -h | fgrep \*

    Rerun the analysis using appropriate assertions to find out where the variables are being accessed without holding the proper locks.

    Remember that you cannot run analyze twice for a given state, so it will probably help to save the state of LockLint using the save subcommand before running analyze. Then restore that state using refresh or restore before adding more assertions. You may want to set up an alias for analyze that automatically does a save before analyzing.