SOLID概要

(前ページへ)

実行時アドレスバグ自動検出機能の有効な使い方

検出対象を指定することで、オーバーヘッドの影響を少なく

上記のように、アドレスサニタイザモードでの動作時にはメモリの消費量および実行時間に対するオーバーヘッドがあるため、制御対象によっては正常に動作しない場合もあると思います。しかし、アドレスサニタイザモードでは、「特定のプロジェクトだけ」「特定の関数だけ」を検出対象に指定できるという便利な使い方が可能です。

そのため、プロジェクト単位でアドレスサニタイザを利用したり、個別の関数単位でアドレスサニタイザモードを用いて予め検証し、結合時テストではアドレスサニタイザモードを全て外す、といった使い方でオーバーヘッドの影響を少なくすることが可能です。

一般的なテスト検証においては、バグがどこに影響を及ぼすかがわからないため、ソフトウェア全体を結合した状態で影響範囲の検証を行う必要があります。しかしアドレスサニタイザでは影響を及ぼされた側ではなく、影響を及ぼした側の不正アクセスを「現行犯逮捕」できる仕組みです。そのため、部分的に分割してアドレスサニタイザを適用したデバッグでも、不正アクセスの検出に十分有効です。

チーム開発時のリビジョンアップ作業も安心

ソフトウェアの規模が大きくなりチーム体制で開発する場合、担当モジュールを更新してリリースする前にアドレスサニタイザモードを有効にして実行テストをしておけば、他のモジュールへ影響を与えないことが確認できるため、安心してモジュールの更新&リリースが出来ます。

アドレスサニタイザ機能のSOLID流アレンジ

memset()、memcpy()関数では効率よくメモリをチェックする

アドレスサニタイザモードにおいては、メモリアクセス命令を実行する度に対象のメモリが有効か無効かを判定するチェックルーチンを実行しています。そのため、memset()やmemcpy()といったメモリブロック操作関数では操作対象の全アドレスに対してメモリアクセスの都度 有効無効チェックが実行され、実行時間のオーバーヘッドが大きくなってしまうという懸念があります(図3-4 左)。

そこでSOLIDでは独自の機能で対処しています。まず、SOLIDで用意しているライブラリのmemset()およびmemcpy()で行われるメモリアクセスは、アドレスサニタイザの対象から除外されています。

そのうえで、関数の先頭で一度だけ操作対象アドレスの全範囲が有効か無効かをチェックし、一部でも無効アドレスであれば、アドレスバグとして検出を行うよう、SOLID独自のAPIを用意してオーバーヘッドを少なくしています。逆に全域が有効アドレスであればメモリブロック操作命令を実行します。(図3-4 右)。

図3-4 メモリブロック操作命令では、SOLID が独自にアドレスチェック回数を少なくする

ここで使用した「特定の命令や関数をアドレスサニタイザの対象から除外する機能」は、Clangコンパイラが持っている機能です。この機能と、SOLID独自の「APIを活用してアドレスサニタイザのアドレスチェック回数を削減する仕組み」を活用することで、メモリブロック操作におけるアドレスチェックルーチンの実行回数(実行時間のオーバーヘッド)を大幅に削減することができます。

malloc、free 関数によるメモリの動的割り当ても監視

SOLID独自の機能として、malloc、free関数によるメモリの動的割り当ても監視しています。

アドレスサニタイザモードでは、malloc関数が実行された場合に、当該アドレス領域に対してアドレス有効・無効テーブルを「有効」にセットし、free関数が実行されたら、その領域は「無効」にします。また、malloc、free関数の先頭では、アドレス有効・無効テーブルのチェックをするルーチンを追加します。

プログラムを実行中、free関数実行の際に既にその領域が「無効」になっていた場合は、「二重解放」に当たるため、SOLIDはこれを不正動作として検出し、プログラムをブレークしてデバッガを通してユーザーに通知します。

同様に、free関数実施後に当該アドレス領域をアクセスした場合も、不正動作として検出します。

ブレークした箇所を分かりやすく表示

これまでご紹介してきたように、アドレスサニタイザモードを使ったデバッグではユーザーが作成したプログラムに対して、不正検出やデバッグのためのコード(ランタイム)が多数追加されて走っています。

つまり、アドレスバグを自動検出してプログラムがブレークした瞬間のPC(プログラムカウンタ)は、ユーザーのコードとは別の不正検出やデバッグのためのコードの中にあることになります。

このPCはデバッグ対象であるユーザー自身のコードの中ではないため、デバッガの画面ではブレークしたPCの箇所ではなく、不正の元となったユーザープログラムのソースコードの箇所を分かりやすく表示する工夫をしています。またトレース履歴にはブレークするまでに走ったコードのトレース情報が不正検出用のコードを含めて記録されていますが、不正が発生したユーザーコードの箇所が判るように表示をする、といった配慮もしています。

(次ページ 利用者の体験から)