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:
Writable variable read while no locks held!
Variable written while no locks held!
No lock consistently held while accessing variable!
Output from the analyze subcommand can be particularly abundant if:
The code has not been analyzed before
The assert read only subcommand was not used to identify read-only variables
No assertions were made about the protection of writable variables
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.
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:
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.
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.
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.
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.)
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.
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.
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.
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.
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.)
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.