Analyzing Program Performance With Sun WorkShop

analyze

analyze has the following syntax:


analyze [-hv]

Analyzes the loaded files for lock inconsistencies that may lead to data races and deadlocks. This subcommand may produce a great deal of output, so you may want to redirect the output to a file. This subcommand can be run only once for each saved state. (See "save").

-h (history) produces detailed information for each phase of the analysis. No additional errors are issued.

-v (verbose) generates additional messages during analysis:

The output messages are likely to reflect situations that are not real problems; therefore, it is often helpful to first analyze the code without the -v option, to show only the messages that are likely to represent real problems.

LockLint analyze Phases

Each problem encountered during analysis is reported on one or more lines, the first of which begins with an asterisk. Where possible, LockLint provides a complete traceback of the calls taken to arrive at the point of the problem. The analysis goes through the following phases:

  1. Checking for functions with variable side effects on locks

    If a disallow sequence specifies that a function with locking side effects should not be analyzed, LockLint produces incorrect results. If such disallow sequences are found, they are reported and analysis does not proceed.

  2. Preparing locks to hold order info

    LockLint processes the asserted lock order information available to it. If LockLint detects a cycle in the asserted lock order, the cycle is reported as an error.

  3. Checking for function pointers with no targets

    LockLint cannot always deduce assignments to function pointers. During this phase, LockLint reports any function pointer for which it does not think there is at least one target, whether deduced from the source or declared a func.ptr target.

  4. Removing accesses to ignored variables

    To improve performance, LockLint removes references to ignored variables at this point. (This affects the output of the vars subcommands.)

  5. Preparing functions for analysis

    During this phase, LockLint determines what side effects each function has on locks. (A side effect is a change in a lock's state that is not reversed before returning.) An error results if

    • The side effects do not match what LockLint expects

    • The side effects are different depending upon the path taken through the function

    • A function with such side effects is recursive

    LockLint expects that a function will have no side effects on locks, except where side effects have been added using the assert side effect subcommand.

  6. Preparing to recognize calling sequences to allow/disallow

    Here LockLint is processing the various allow/disallow subcommands that were issued, if any. No errors or warnings are reported.

  7. Checking locking side effects in function pointer targets

    Calls through function pointers may target several functions. All functions that are targets of a particular function pointer must have the same side effects on locks (if any). If a function pointer has targets that differ in their side effects, analysis does not proceed.

  8. Checking for consistent use of locks with condition variables

    Here LockLint checks that all waits on a particular condition variable use the same mutex. Also, if you assert that particular lock to protect that condition variable, LockLint makes sure you use that lock when waiting on the condition variable.

  9. Determining locks consistently held when each function is entered

    During this phase, LockLint reports violations of assertions that locks should be held upon entry to a function (see assert subcommand). Errors such as locking a mutex lock that is already held, or releasing a lock that is not held, are also reported. Locking an anonymous lock, such as foo::lock, more than once is not considered an error, unless the declare one command has been used to indicate otherwise. (See "Lock Inversions" for details on anonymous data.)

  10. Determining locks consistently held when each variable is accessed

    During this phase, LockLint reports violations of assertions that a lock should be held when a variable is accessed (see the assert subcommand). Also, any writes to read-only variables are reported.

    Occasionally you may get messages that certain functions were never called. This can occur if a set of functions (none of which are root functions) call each other. If none of the functions is called from outside the set, LockLint reports that the functions were never called at all. The declare root subcommand can be used to fix this situation for a subsequent analysis.

    Using the disallow subcommand to disallow all sequences that reach a function will also cause a message that the function is never called.

Once the analysis is done, you can find still more potential problems in the output of the vars and order subcommands.