Analyzing Program Performance With Sun WorkShop

Managing LockLint's Environment

The LockLint interface consists of the lock_lint command, which is executed in a shell, and the lock_lint subcommands. By default, LockLint uses the shell given by the environment variable $SHELL. Alternatively, LockLint can execute any shell by specifying the shell to use on the lock_lint start command. This example starts a LockLint session in the Korn shell:


% lock_lint start /bin/ksh

LockLint creates an environment variable called LL_CONTEXT, which is visible in the child shell. If you are using a shell that provides for initialization, you can arrange to have the lock_lint command source a .ll_init file in your home directory, and then execute a .ll_init file in the current directory if it exists. If you use csh, you can do this by inserting the following code into your .cshrc file:


if ($?LL_CONTEXT) then
	if ( -x $(HOME)/.ll_init ) source $(HOME)/.ll_init
endif

It is better not to have your .cshrc source the file in your current working directory, since others may want to run LockLint on those same files, and they may not use the same shell you do. Since you are the only one who is going to use your $(HOME)/.ll_init, you should source that one, so that you can change the prompt and define aliases for use during your LockLint session. The following version of ~/.ll_init does this for csh:


# Cause analyze subcommand to save state before analysis.
alias analyze "lock_lint save before analyze;\
	lock_lint analyze"
# Change prompt to show we are in lock_lint.
set prompt="lock_lint~$prompt"

Also see "start".

When executing subcommands, remember that you can use pipes, redirection, backward quotes (`), and so on to accomplish your aims. For example, the following command asserts that lock foo protects all global variables (the formal name for a global variable begins with a colon):


% lock_lint assert foo protects `lock_lint vars | grep ^:`

In general, the subcommands are set up for easy use with filters such as grep and sed. This is particularly true for vars and funcs, which put out a single line of information for each variable or function. Each line contains the attributes (defined and derived) for that variable or function. The following example shows which members of struct bar are supposed to be protected by member lock:


% lock_lint vars -a `lock_lint members bar` | grep =bar::lock

Since you are using a shell interface, a log of user commands can be obtained by using the shell's history function (the history level may need to be made large in the .ll_init file).

Temporary Files

LockLint puts temporary files in /var/tmp unless $TMPDIR is set.

Makefile Rules

To modify your makefile to produce .ll files, first use the rule for creating a .o from a .c to write a rule to create a .ll from a .c. For example, from:


# Rule for making .o from .c in ../src.
%.o: ../src/%.c
	$(COMPILE.c) -o $@ $<

you might write:


# Rule for making .ll from .c in ../src.
%.ll: ../src/%.c
	cc $(CFLAGS) $(CPPFLAGS) $(FOO) $<

In the above example, the -Zll flag would have to be specified in the make macros for compiler options (CFLAGS and CPPFLAGS).

If you use a suffix rule, you will need to define .ll as a suffix. For that reason some prefer to use % rules.

If the appropriate .o files are contained in a make variable FOO_OBJS, you can create FOO_LLS with the line:


FOO_LLS = ${FOO_OBJS:%.o=%.ll}

or, if they are in a subdirectory ll:


FOO_LLS = ${FOO_OBJS:%.o=ll/%.ll}

If you want to keep the .ll files in subdirectory ll/, you can have the makefile automatically create this file with the label:


.INIT:
	@if [ ! -d ll ]; then mkdir ll; fi