Analyzing Program Performance With Sun WorkShop

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.