Go to main content
Oracle Developer Studio 12.5 Man Pages

Exit Print View

Updated: June 2017
 
 

lock_lint(1)

Name

lock_lint - verify use of locks in multi-threaded programs

Synopsis

lock_lint subcommand

Description

LockLint is a tool that statically analyzes ANSI C source code to aid in the detection of data races and deadlocks caused by inconsistent usages of mutex and readers-writer locks. LockLint supports the ANSI C programmer using the Oracle Solaris libthread API feature.

There are two interfaces for LockLint:

subcommands

These are entered from a command line (or from a script) and take the form:

lock_lint subcommand
source code annotations

These are entered directly into your source code. Although there are fewer source code annotations than subcommands, they are often preferable to subcommands.

To start a LockLint session, type:

lock_lint start

This starts a user-specifiable subshell with an appropriate LockLint context established. (See the start subcommand, below, for more information.)

For LockLint to analyze your source code, the code must first be compiled using the -Zll option of the C compiler. The C compiler then produces the LockLint database files (.ll files), one for each .c file compiled. The .ll files will later be loaded into LockLint via the load subcommand.

Sub Commands

For quick information on any LockLint subcommand while you're in a LockLint session, use the LockLint help subcommand (see below).

For efficiency and ease, you can alias subcommands (if your shell allows it); you can also put subcommands into a script file and run that script.

analyze [-hv]

Analyze the loaded files for lock inconsistencies which 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 directive can only be run once for each saved state (see save).

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

lock_lint vars -h | fgrep *

will show variables which are not properly protected by any lock.

assert side effect mutex acquired in func ...
assert side effect rwlock [read] acquired in func ...
assert side effect mutex|rwlock released in func ...
assert side effect rwlock upgraded|downgraded in func ...
assert mutex|rwlock protects var ...
assert mutex protects func ...
assert rwlock protects [reads in] func ...
assert order lock lock ...
assert read only var ...
assert rwlock covers lock ...

Provide LockLint with assertions about how locks are being used. During analysis LockLint reports on any violations of these assertions.

declare mutex mutex ...
declare rwlocks rwlock ...
declare func_ptr targets func ...
declare nonreturning func ...
declare one tag ...
declare readable var ...
declare root func ...

Declare various attributes about locks, functions and variables in the program.

disallows

List the calling sequences which are disallowed, as specified using the disallow subcommand.

exit

To exit LockLint, use the exit command of the shell you are using. When the subshell started by the lock_lint start command exits, LockLint exits.

files

List the source code files as represented by the .ll files loaded via the load subcommand.

funcptrs [-botu] func_ptr ...
funcptrs [-blotuz]
funcptrs [-botu] func_ptr ...
funcptrs [-blotuz]

List information about the function pointers used in the loaded files.

funcs [-adehou] func ...
funcs [-adehilou]
funcs [-adehlou] [directly] called by func ...
funcs [-adehlou] [directly] calling func ...
funcs [-adehlou] [directly] reading var ...
funcs [-adehlou] [directly] writing var ...
funcs [-adehlou] [directly] accessing var ...
funcs [-adehlou] [directly] affecting lock ...
funcs [-adehlou] [directly] inverting lock ...

List information about the functions defined and/or called in the loaded files.

help [subcommand]

The help subcommand with no topic specified gives a list of subcommands with their options and some general help information. Detailed help on a subcommand can be specified via the syntax:

lock_lint help first word of subcommand

Help is also available on the following keywords:

 
condvars       inversions        names
example        limitations       overview
exit              locking           shell
ifdef             makefile
shell
ignore func|var ... [in func ... ]

Tell LockLint to exclude certain functions and variables from the analysis. This exclusion may be limited to specific functions using the "in func ..." clause; otherwise the exclusion applies to all functions.

load file ...

Load the specified .ll files. The extension may be omitted, but if an extension is specified, it must be .ll. Absolute and relative paths are allowed. The following are legal (depending upon your shell's capabilities):

 
lock_lint load *.ll
lock_lint load ../foo/abcdef{1,2}
lock_lint load `find . -name ll
locks [-co] lock ...
locks [-clo]
locks [-clo] [directly] affected by func ...
locks [-clo] [directly] inverted by func ...

List information about the locks of the loaded files. Note that only those variables which are actually used in lock manipulation routines are shown; locks which are simply declared but never manipulated will not be shown.

members struct_tag

List the members of the struct with the specified tag, one per line. For structures which were not assigned a tag, the notation "file@line is used (e.g. "x.c@29"), where the file and line number are the source location of the struct's declaration.

order [lock [lock]].

List information about the order in which locks are acquired by the code being analyzed. It may only be run after analysis is complete.

pointer calls

List calls made through function pointers in the loaded files.

reallow func ...

Allow exceptions to disallow subcommands.

reallows

List the calling sequences which are reallowed, as specified using the reallow subcommand.

refresh

Pop the saved state stack restoring LockLint to the state of the top of the saved state stack. The description associated with that state is printed. Then save the state again with the same description (so that it may be restored/refreshed again).

restore

Pop the saved state stack restoring LockLint to the state of the top of the saved state stack. The description associated with that state is printed.

save description

Save the current state of the tool on a stack. The specified description is attached to the state. Saved states form a LIFO (Last-In-First-Out) stack, so that the last state saved is the first one restored.

saves

List the descriptions of the states saved on the saved stack via the save subcommand. The descriptions are shown from top to bottom with the first description being the most recently saved state that has not been restored. And the last description being the oldest state saved that has not been restored.

start cmd

Start a LockLint session. A LockLint session must be started prior to using any other LockLint subcommand. By default the start subcommand establishes LockLint context and starts a subshell for the user -- as specified via $SHELL -- within that context. The only piece of the LockLint context exported to the subshell is the LL_CONTEXT environment variable. LL_CONTEXT contains the path to the temporary directory of files used to maintain a LockLint session.

sym name ...

List the various things the specified names could refer to within the loaded files. For example, "foo" might refer both to variable "x.c:func1/foo" and to function y.c:foo, depending on context.

unassert vars var ...

Undo any assertion about locks protecting the specified variables. Note that there is no way to remove an assertion about a lock protecting a function.

vars [-aho] var ...
vars [-ahilo]
vars [-ahlo] protected by lock
vars [-ahlo] [directly] read by func...
vars [-ahlo] [directly] written by func ...
vars [-ahlo] [directly] accessed by func ...

List information about the variables of the loaded files. Note that only those variables which are actually *used* are shown; variables which are simply declared in the program but never accessed will not be shown.

SOURCE CODE ANNOTATIONS

ASSERT(NO_LOCKS_HELD);
assert(NO_LOCKS_HELD);

Tell LockLint that when this point in the code is reached, no locks should be held by the thread executing this test. Violations will be reported during analysis.

ASSERT(NO_COMPETING_THREADS);
assert(NO_COMPETING_THREADS);

Tell LockLint that when this point in the code is reached, no other threads should be competing with the one running this code. Violations (based on info provided by certain NOTE-style assertions) are reported during analysis.

ASSERT(MUTEX_HELD(lock_expr) && ...);
assert(MUTEX_HELD(lock_expr) && ...);

Cause an error to be reported if the executing thread does not hold the lock as described.

NOTE(MUTEX_PROTECTS_DATA(Mutex, DataNameList));
NOTE(RWLOCK_PROTECTS_DATA(Rwlock, DataNameList));
NOTE(SCHEME_PROTECTS_DATA("description", DataNameList));

The first two annotations tell LockLint that the lock should be held whenever the specified data are accessed.

The third annotation, SCHEME_PROTECTS_DATA, describes how data which are not protected by a mutex or readers/writer lock are protected. The description supplied for the scheme is simply text.

NOTE(READ_ONLY_DATA(DataNameList));

Tell LockLint that the data should only be read, and not written.

NOTE(DATA_READABLE_WITHOUT_LOCK(DataNameList));

Tell LockLint that the specified data may be read without protecting locks being held on them.

NOTE(RWLOCK_COVERS_LOCKS(RwlockName, LockNameList));

Tell LockLint that a hierarchical relationship exists between a readers/writer lock and a set of other locks.

NOTE(MUTEX_ACQUIRED_AS_SIDE_EFFECT(MutexExpr));
NOTE(READ_LOCK_ACQUIRED_AS_SIDE_EFFECT(RwlockExpr));
NOTE(WRITE_LOCK_ACQUIRED_AS_SIDE_EFFECT(RwlockExpr));
NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(LockExpr));
NOTE(LOCK_UPGRADED_AS_SIDE_EFFECT(RwlockExpr));
NOTE(LOCK_DOWNGRADED_AS_SIDE_EFFECT(RwlockExpr));
NOTE(NO_COMPETING_THREADS_AS_SIDE_EFFECT);
NOTE(COMPETING_THREADS_AS_SIDE_EFFECT);

Tell LockLint that the function has the specified side effect on the specified lock - that is, that the function deliberately leaves the lock in a different state on exit than it was in when the function was entered. In the case of the last two of these annotations, the side effect is not about a lock but rather about the state of concurrency.

NOTE(COMPETING_THREADS_NOW);
NOTE(NO_COMPETING_THREADS_NOW);

The first annotation tells LockLint that after this point in the code, other threads exist which might try to access the same data that this thread will access. The second function specifies that this is no longer the case, that either no other threads are running, or whatever threads are running will not be accessing data that this thread will access.

NOTE(NOT_REACHED);

Tell LockLint that a particular point in the code cannot be reached, and therefore LockLint should ignore the condition of locks held at that point. Lock Order

NOTE(LOCK_ORDER(LockNameList));

Specify the order in which locks should be acquired.

NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(DataExpr, ...));
NOTE(NOW_VISIBLE_TO_OTHER_THREADS(DataExpr, ...));

Tell LockLint whether or not the variables represented by the specified expressions are visible to other threads - that is, whether or not other threads could access the variables.

NOTE(ASSUMING_PROTECTED(DataExpr, ...));

Tell LockLint that this function assumes that the variables represented by the specified expressions are protected - that is, either the appropriate lock is held for each variable; or the variables are invisible to other threads; or there are no competing threads when the call is made.

Environment Variables

LL_CONTEXT

contains path to context directory

SHELL

used as default shell

TMPDIR

used as default tmp directory path

See Also

For complete Oracle Developer Studio documentation, go to http://www.oracle.com/technetwork/server-storage/solarisstudio/documentation

CAVEATS

Currently, LockLint does not check to see if a .ll is out of date with respect to its source file.

Files

file.ll

LockLint database file from cc

lock_lint

lock_lint command

lock_lint_server

LockLint engine

help

directory of help files

cmd.ll_help

help topic on cmd

Errors

Exit status from a lock_lint command is as follows:

0

Normal

1

System error

2

User caused error, like incorrect options or undefined name

3

Multiple types of errors

5

Lock_lint detected error: violation of an assertion potential data race or deadlock may have been found, unprotected data references, etc.

10

Licensing error