Analyzing Program Performance With Sun WorkShop

Limitations of LockLint

There are limitations to LockLint's powers of analysis. At the root of many of its difficulties is the fact that LockLint doesn't know the values of your variables.

LockLint solves some of these problems by ignoring the likely cause or making simplifying assumptions. You can avoid some other problems by using conditionally compiled code in the application. Towards this end, the compiler always defines the preprocessor macro __lock_lint when you compile with the -Zll option. You can use this macro to make your code less ambiguous.

LockLint has trouble deducing:

Some other LockLint difficulties:

During analysis, LockLint may produce messages about a lock operation called rw_upgrade. Such a call does not really exist, but LockLint rewrites code like


if (rw_tryupgrade(&lock1)) { 		...  	}

as


if () { 		rw_tryupgrade(&lock1); 		...  	}

such that, wherever rw_tryupgrade() occurs, LockLint always assumes it succeeds.

One of the errors LockLint flags is an attempt to acquire a lock that is already held. However, if the lock is unnamed (for example, foo::lock), this error is suppressed, since the name refers not to a single lock but to a set of locks. However, if the unnamed lock always refers to the same lock, use the declare one subcommand so that LockLint can report this type of potential deadlock.

If you have constructed your own locks out of these locks (for example, recursive mutexes are sometimes built from ordinary mutexes), LockLint will not know about them. Generally you can use #ifdef to make it appear to LockLint as though an ordinary mutex is being manipulated. For recursive locks, use an unnamed lock for this deception, since errors won't be generated when it is recursively locked. For example:


void get_lock() {
	#ifdef __lock_lint 
			struct bogus *p;
			pthread_mutex_lock(p->lock);
	#else
			<the real recursive locking code>
	#endif
}