スポンサーサイト 

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

引き継いだソースコードをヤバイと思う瞬間 

「一生あなたがそのプログラムをメンテナンスするならいいけどね」

 

企業でプログラムを書いていれば一度は聞いたことがあるかと思います。 他人が書いたプログラムを引き継ぐということはごく普通にあります。RTOSなどが使われているそれなりの規模のプログラムを引き継ぐとき、 今までよくこれで問題がでないかったなぁと思うようなソースコードを渡されることがあります。 プロダクトによって見るべきポイントはいろいろあると思いますが、引継ぎ時に私が最低チェックを入れるポイントを挙げてみました。

 

まず、基本中の基本ですが組み込みソフトウェアの場合、汎用ポートを制御することが多く見られます。 システムが(起動時など特定の場合を除いて)通常稼動している際の処理で汎用ポートレジスタを特定のビットを1にしたり0にしたりするような場合に何のためらいもなく

*PORT_ADDRESS |= PORT_BIT;

のような記述をされているときです。他のビットを別のタスクや割り込みハンドラ内で制御している場合に非常に危険です。 仮に今扱っているハードウェアでは大丈夫でも、次の(試作も含めて)ハードウェアでピンの割り当てが変わらない保障はどこにもありません。 ちゃんと排他処理を行うべきです。

 

次にヤバイと思うパターンは割り込みハンドラ内でのグローバル変数へのライトアクセスです。以下はあまり現実的な例ではありませんが、 プログラムがふっとぶ可能性があります。

#define TABLE_MAX 10
int counter = 0;

void handler(void) { counter++ }

void func(int *table)
{
    if (counter < TABLE_MAX) {
        table[counter]++;
    }
    else {
        counter = 0;
    }
}

この例では排他処理やローカル変数を使うことで回避できますし、そのように記述されることも多いと思います。ただ、多くの場合、 OSなどのサービスを除くとメインループと割り込みハンドラという関係において割り込みハンドラ内でライトアクセスを行わなくてもプログラムは記述できることを意識することが重要です。 もちろんやむを得ない理由や最適化の結果としてライトアクセスを行うケースがあるのは認識していますが、 そのような場合は必ずソースコードにコメントをつけるべきです。 何のコメントもなくライトアクセスしているようなコードは危険性を疑ってみるべきです。

 

典型的なケースで一番困るのが状態管理用変数の継ぎ足しや流用でしょう。 開発が進むにしたがって当初考えていたよりも状態の定義が不十分であることが明確になってきます。 不十分であることがが発覚するたびに状態管理用変数の追加や流用が行われるわけです。 条件文のネストの中に状態管理用変数が再登場したり登場の順番が入れ替わっていたり、 3つ以上の変数を使用しているにもかかわらずなんのドキュメントも無い様な場合、やはりヤバイといえるでしょう。 高い確率でその変数はグローバル変数になっているはずです。

 

逆に安心感のあるコードのパターンとしては、 割り込みハンドラの中身を所有しているモジュールにおいてその割り込みの制御をモジュールの使用者にまかせずにモジュール内に隠蔽しているようなソースコードです。 特にそのモジュールがタスクも所有している場合、割り込み制御の隠蔽はそれなりに考えていなければできないものです。

 

油断しているとすぐにソースコードはヤバイものになります。 自分なりのべからず集を頭の中からアウトプットしておくことは自戒の意味においても大切ではないでしょうか。

 

コメント

コメントの投稿















管理者にだけ表示を許可する

トラックバック

この記事のトラックバックURL
http://ochoo.blog48.fc2.com/tb.php/82-209587f5

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。