マニュアルページ lock_lint.1
名前
lock_lint - マルチスレッドプログラムでロックの使用法を検証
形式
lock_lint subcommand
機能説明
ロック lint は ANSI C のソースコードを静的に解析するこ と に
よっ て、一貫していない相互排他ロックや読み取り/書き込みロッ
クによるデータ競合やデッドロックを検出するためのツールです。
ロッ ク lint は Solaris の libthread API を使用している ANSI
C のプログラマをサポートしています。
ロック lint には、次の 2 つのインタフェースがあります。
サブコマンド
コマンド行 (またはスクリプト) から次の書式で指 定 し ま
す。
lock_lint subcommand
ソースコード注釈
ソースコードに直接入力します。サブコマンドより数は少 な
いですが、サブコマンドよりも好まれるようです。
ロック lint セッションを開始するには、次のように入力します。
lock_lint start
このサブコマンドは、既存の適切なロック lint 実行環境を 持 つ
ユー ザー指定のサブシェルを起動します。詳細は "start" サブコ
マンドの説明を参照してください。
ロック lint がソースコードを解析するためには、最初に C コ ン
パイラの -Zll オプションを使用してそのコードをコンパイルして
おかなければなりません。次に C コンパイラは、コンパイル済 み
の 各 .c ファイルに 1 つずつロック lint のデータベースファイ
ルを生成します。.ll ファイルは、load サブコマンドによって 後
か らロック lint にロードされます ("load" サブコマンドの説明
を参照)。
サブコマンド
ロック lint サブコマンドの一覧を調べるには、次のコマンドを使
用します。
lock_lint help
サブコマンドにはわかりやすい別名を付けることができます (ご使
用 のシェルによります)。また、複数のサブコマンドをスクリプト
ファイルに入れて、そのスクリプトを実行することも可能です。
analyze [-hv]
ロードされたファイルについて、データ競合およ び デッ ド
ロッ クを引き起こす可能性のあるロックの不一致を解析しま
す。このサブコマンドからは結果が大量に出力されます が、
ファ イルにその出力をリダイレクトすることもできます。こ
の指令は、保存された各状態に対して 1 度だけ実行すること
ができます ("save" サブコマンドの説明を参照)。
この解析が終了しても、"vars" および "order" サブコマ ン
ド の出力の中に、まだ潜在的な問題が残っているのがわかり
ます。たとえば、次のコマンド行では、ロックによって正 し
く保護されていない変数を表示します。
lock_lint vars -h | fgrep *
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 ...
これらのサブコマンドは、ロックの使用に関する表明を行 い
ま す。解析中ロック lint は、これらの表明に違反があると
報告します。
declare mutex mutex ...
declare rwlocks rwlock ...
declare func_ptr targets func ...
declare nonreturning func ...
declare one tag ...
declare readable var ...
declare root func ...
これらのサブコマンドは、プログラム中のロック、関数、 変
数についてのさまざまな属性を宣言します。
disallows
disallow サブコマンドを使用して指定された呼び出しシーケ
ンスを列挙します。
exit
ロック lint を終了するには、使用中のシェルの終了コマ ン
ド を実行してください。"lock_lint start" コマンドで起動
されたサブシェルを終了すると、ロック lint も終 了 し ま
す。
files
load サブコマンドを介してロードされる .ll ファイルに 表
現されているように、ソースコードファイルを列挙します。
funcptrs [-botu] func_ptr ...
funcptrs [-blotuz]
funcptrs [-botu] func_ptr ...
funcptrs [-blotuz]
これらのサブコマンドは、ロードされたファイルで使用さ れ
る関数ポインタの情報を列挙します。
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 ...
このサブコマンドは、ロードされたファイルで定義または 呼
び 出し、あるいはその両方が行われている関数情報を列挙し
ます。
help [subcommand]
help の後にサブコマンド名 subcommand を指定すると、その
サ ブコマンドについての詳細な情報を表示することができま
す。また subcommand を指定しないで次のように入 力 す る
と、 サブコマンドの一覧とそれらの簡単な説明が表示されま
す。
lock_lint help
サブコマンドの他に、次のキーワードに関する情報も用意 さ
れています。
condvars 条件変数について
example 使用例の紹介
ifdef ifdef の使用について
inversions ロックの逆転について
limitations ロック lint の制限事項について
locking ロック呼び出しについて
makefile メークファイルを記述する際の規則について
names 名前の形式について
overview ロック lint の概要について
shell シェルについて
ignore func|var ... [in func ... ]
このサブコマンドは、ある関数と変数を解析から無視する よ
う ロッ ク lint に 指 定します。無視される対象は、"in
func..." 句を指定すると指定の関数 func ... のみになりま
すが、"in func..." 句を指定しなければすべての関数が無視
の対象となります。以下のコマンドは、どの関数と変数が 無
視されているかを表示します。
load file ...
指定の .ll ファイル file ... をロードします。接尾辞は省
略してかまいませんが、指定する場合は必ず .ll にしてくだ
さい。パスは絶対パスと相対パスのどちらでもかま い ま せ
ん。次の指定は正当です (ただしシェルの機能によります)。
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 ...
ロードされたファイルのロックについての情報を列 挙 し ま
す。 ロックを操作する関数で実際に使用されている変数だけ
が表示されることに注意してください。宣言されるだけ で、
操作されないロックは表示されません。
members struct_tag
指定されたタグ struct_tag のある構造体のメンバを 1 行ご
と に列挙します。タグが割り当てられていない構造体に対し
ては、"ファイル@行番号" ("x.c@29" など) という表記が 使
用 されます。"ファイル@行番号" は、構造体が宣言されてい
るソースの位置です。
order [lock [lock]].
解析中のコードによって獲得されるロックの順序について の
情報を列挙します。このサブコマンドは、必ず analyze サブ
コマンドの後で実行してください。
pointer calls
ロードされたファイル内の関数ポインタによって行われた 呼
び出しを列挙します。
reallow func ...
disallow サブコマンドが適用されるときの例外を作成 し ま
す。
reallows
reallow サブコマンドで指定することによって再び解析で き
るようになった呼び出しシーケンスを列挙します。
refresh
状態保存スタックをポップして、ロック lint の状態を保 存
前 に戻します。その状態名が表示されます。次に、ただちに
同じ状態名で状態を再保存 (プッシュ) します (そのた め、
復元/再保存されます)。
restore
状態保存スタックをポップして、ロック lint の状態を保 存
前に戻します。その状態名が表示されます。
save description
スタック上にロック lint の現在の状態を保存します。指 定
の description は状態の名前になります。状態は LIFO (後
入れ先出し) スタックに保存されるため、最後に保存され た
状態が最初に復元されます。
saves
save サブコマンドによってスタックに保存された状態名を列
挙 します。最後に保存されてまだ復元されていない状態の最
初の記述から、最初に保存されてまだ復元されていない状 態
である最後の記述まで、すべての状態名が表示されます。
start cmd
ロック lint セッションを開始します。ロッ ク lint セッ
ショ ンは、他のロック lint サブコマンドを使用する前に開
始されなければなりません。デフォルトでは、start サブ コ
マ ン ド はロック lint の実行環境を確立し、実行環境内で
$SHELL によって指定されたユーザー用サブシェルを起動しま
す。 シェルにエクスポートされるロック lint 実行環境の唯
一の部分が、環境変数 LL_CONTEXT です。 LL_CONTEXT は、
ロッ ク lint セッションを維持するために使用されるファイ
ルの一時ディレクトリのパスを含んでいます。
sym name ...
ロードされたファイル内で指定した名前 name で参照でき る
も のを列挙します。たとえば実行環境によって、"foo" は変
数である "x.c:func1/foo" を表す 場 合 と 関 数 で あ る
"y.c:foo" を表す場合の両方があります。
unassert vars var ...
指定の変数 var ... を保護するロックについての表明を取り
消 します。関数を保護するロックについての表明は削除でき
ないことに注意してください。
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 ...
ロードされたファイル内の変数についての情報を列 挙 し ま
す。 実際に使用される変数だけが表示されることに注意して
ください。プログラム内で宣言されただけでアクセスされ な
い変数は表示されません。
ソースコード注釈
ASSERT(NO_LOCKS_HELD);
assert(NO_LOCKS_HELD);
ロック lint は、この表明があると、コードのこの位置に 到
達 した時点でこの判定を実行しているスレッドによって保持
されているロックはないはずであると認識します。これに 対
して違反がある場合は、解析中に報告されます。
ASSERT(NO_COMPETING_THREADS);
assert(NO_COMPETING_THREADS);
ロック lint は、この表明があると、コードのこの位置に 到
達 した時点でこのコードを実行しているスレッドと競合する
他のスレッドはないはずであると認識します。これに対す る
違反がある (NOTE 形式の何らかの表明によって得られる情報
にもとづいて判断) 場合は、解析中に報告されます。
ASSERT(MUTEX_HELD(lock_expr) && ...);
assert(MUTEX_HELD(lock_expr) && ...);
実行中のスレッドが記述どおりのロックを保持していない 場
合に、エラーが報告されます。
NOTE(MUTEX_PROTECTS_DATA(<相互排他ロック>, <データ名リスト>))
NOTE(RWLOCK_PROTECTS_DATA(<読み取り/書き込みロック>, <データ名リスト>))
NOTE(SCHEME_PROTECTS_DATA("<記述>", <データ名リスト>))
始めの 2 つの注釈は、指定のデータがアクセスされるときは
常 にロックを保持するようロックリントに知らせます。3 番
目の注釈 SCHEME_PROTECTS_DATA は、相互排他または読み 取
り/書き込みロックでは保護されないデータをどのように保護
するかを記述したものです。この構造で指定する <記述> は
単なる文字列であり、重要な意味はありません。
NOTE(READ_ONLY_DATA(<データ名リスト>))
データが読み取り専用であり、書き込んではならないこと を
ロック lint に知らせます。
NOTE(DATA_READABLE_WITHOUT_LOCK(<データ名リスト>))
保護ロックを保持せずに指定のデータを読み取れる こ と を
ロック lint に知らせます。
NOTE(RWLOCK_COVERS_LOCKS(<読み取り/書き込みロック名>,
<ロック名リスト>))
読み取り/書き込みロックと他のロックの集合との間に階層的
な関係があることをロック lint に知らせます。
NOTE(MUTEX_ACQUIRED_AS_SIDE_EFFECT(<相互排他式>))
意味:副作用として相互排他ロックが獲得される
NOTE(READ_LOCK_ACQUIRED_AS_SIDE_EFFECT(<読み取り/書き込みロック式>))
意味:副作用として読み取りロックが獲得される
NOTE(WRITE_LOCK_ACQUIRED_AS_SIDE_EFFECT(<読み取り/書き込みロック式>))
意味:副作用として書き込みロックが獲得される
NOTE(LOCK_RELEASED_AS_SIDE_EFFECT(<ロック式>))
意味:副作用としてロックが解放される
NOTE(LOCK_UPGRADED_AS_SIDE_EFFECT(<読み取り/書き込みロック式>))
意味:副作用としてロックが昇格される
NOTE(LOCK_DOWNGRADED_AS_SIDE_EFFECT(<読み取り/書き込みロック式>))
意味:副作用としてロックが降格される
NOTE(NO_COMPETING_THREADS_AS_SIDE_EFFECT)
意味:副作用として競合するスレッドはない
NOTE(COMPETING_THREADS_AS_SIDE_EFFECT)
意味:副作用として競合するスレッドがある
関数が指定のロックに対して指定の副作用をもつことを ロッ
ク lint に知らせます。つまり、関数が、終了時のロック状
態を入り口でのロック状態とは意図的に異なる状態にする と
いうことです。上に列挙した注釈のうち最後の 2 つの副作用
は、ロックではなく並行性に関するものです。
NOTE(COMPETING_THREADS_NOW);
NOTE(NO_COMPETING_THREADS_NOW);
最初の注釈は、コードのこの位置以降ではこのスレッドが ア
ク セ ス するのと同じデータにアクセスしようとする他のス
レッドが存在することをロック lint に知らせます。2 番 目
の 関数は競合の状況が終了したこと、つまり実行中の他のス
レッドがないか、または実行中のどのスレッドもこのス レッ
ド が ア クセスするデータにはアクセスしないことを示しま
す。
NOTE(NOT_REACHED);
コードの特定の位置に到達できないこと、したがってその 位
置 で 保 持されているロックの状況を無視することをロック
lint に知らせます。
NOTE(LOCK_ORDER(<ロック名リスト>))
ロックを獲得する順序を指定します。
NOTE(NOW_INVISIBLE_TO_OTHER_THREADS(<データ式>, ...))
NOTE(NOW_VISIBLE_TO_OTHER_THREADS(<データ式>, ...))
指定の式で表現される変数が他のスレッドから可 視 (VISI-
BLE) であるか、あるいは不可視 (INVISIBLE) であるか、つ
まり他のスレッドがその変数をアクセスできるかど う か を
ロック lint に知らせます。
NOTE(ASSUMING_PROTECTED(<データ式>, ...))
指定の式によって表現される変数が以下に示す方法のどれ か
で 保 護 されているとみなすことをロック lint に知らせま
す。
o 各変数に対して適切なロックが保持されている
o 変数が他のスレッドから不可視である
o 呼び出し時に衝突するスレッドがない
環境変数
LL_CONTEXT 実行環境のパスを設定
SHELL デフォルトのシェルを設定
TMPDIR デフォルトの一時ディレクトリのパスを設定
関連項目
Readme ファイル、ユーザーズガイド、リファレンスマニュアル な
どは、 /opt/SUNWspro/docs/index.html
からアクセスできます。コンパイラおよびツールが
/opt 以外のディレクトリにインストールされている場合は、シス
テム管理者に実際のパスをお尋ねください。
注意
現在ロック lint は .ll ファイルがソースファイルに対して古 く
なっているかどうかの検査を行いません。
ファイル
file.ll cc からのロック lint 用データベースファイル
lock_lint ロック lint コマンド
lock_lint_server ロック lint エンジン
help ヘルプファイルのディレクトリ
cmdll_help cmd に関するヘルプ情報ファイル
エラー
ロック lint サブコマンドの終了状態 (exit status) は次のと お
りです。
0 正常
1 システムエラー
2 ユーザーエラー (オプションが正しくない、未定義の名前など)
3 複数のエラー
5 ロック lint がエラーを検出した (表明違反、データ競合や
デッドロックの可能性を検出した、保護されていないデータを
参照した、など)
10 ライセンスエラー