パスワードを忘れた? アカウント作成
25781 story
バグ

静的プログラム解析ツールの実力は? 100

ストーリー by nabeshin
プログラム洗濯機 部門より

あるAnonymous Coward 曰く、

組み込み系の開発では様々なベンダーが次世代静的プログラム解析ツールともいえる製品を開発し、世に送り出している(本家/.記事)。これらツールはNULLポインタ参照やバッファオーバーフローの脆弱性、競合状態やメモリリークなどを検知できるとされている。本家では、Linuxカーネルで使われているsparseのほか、FindBugsや、DoubleCheckIdentify critical defectsなどといったツールが話に出ている。

実際、次世代静的プログラム解析ツールを導入することで開発方法やテストサイクルに変化はあるのだろうか? 新しい解析ツールは既存のものよりそんなに実力が違うのだろうか? 諸氏のご意見を求む。

この議論は賞味期限が切れたので、アーカイブ化されています。 新たにコメントを付けることはできません。
  • 警告を無視したり、出てくる指摘に「逃げる」ようなコードで対処するプログラマばかりの世界では、まったく品質は向上しない。そして困ったことにそういう所こそ、品質を向上させなくてはいけない元凶だったりする。

    # しかも、周りがヤイのヤイの言っても、今まで一度も直らなかったぐらい
    # 上から下まで、ものを判っていない。

    というわけで、このようなツールを使ったからどう、という事ではありません。
    このようなツールの出力にどう対処するかが問題。また、このようなツールが
    出してくる警告の量から、プログラム改善にかかる時間を正確に見積もる、などの
    マネージメント能力も大事でしょう。
    --
    fjの教祖様
    • もっとも、そういう所ではその手のツールの導入以前に、まず「-Wall -Werror」から始める必要がある。
      # みたいなー。
      親コメント
      • by ots556556 (34248) on 2008年05月21日 16時04分 (#1347732)
        「見てください、こんなに頑固な警告も機械的にキャストするだけで…ほら!」
        「わあ!見る見る消えていきますね!」

        # 符号無し整数型の変数と負数のエラー定数を比較した、あの頃の記憶
        親コメント
      • -Wall -Werror は「何が問題か」は教えてくれますが、どう直せばいいのかは教えてくれません。

        そしてそういう人たちは、「何が問題なのか」をいくら説明しても馬耳東風なのです。

        「で、どうすればいいって~~??!」

        一瞬「この世から消えろ」と「プログラマ辞めろ」とどっちを先に言おうか悩んだのは秘密だ。
        そして実際に言ったせりふは…

        「… あぁ… どうやら天もあなたの今の発言には怒り狂ったようですね。
         寝言は寝て言うように」

        # fjの教祖様の怒りが頂点に達すると、雷が天から降り注ぐ…ときもあるのだ。
        --
        fjの教祖様
        親コメント
        • > -Wall -Werror は「何が問題か」は教えてくれますが、どう直せばいいのかは教えてくれません。

          いやいや普通なら、
          「Warnningは全部消せ。」
          「消せないなら、消せない理由を報告書を書いて出せ。」
          って、いっておくだけで、
          みんな必死にシンタックスな問題からセマンティックな問題に昇華してくれます。
          書類、書くの嫌いだから。

          セマンティックな問題は、コードレビューしか対処方法はないですよね?

          コードレビューは、レビュアという教育者を育てるし、
          プログラマ教育の教材そのものではないですか。

          バグはでるものと割り切って、バグを多く出すレビュアを、
          首にするなり、再教育するなり、調教するなり、
          そこまできたらマネージャー自由にしてもいいですよね。

          # という、牧歌的な時代はとうの昔に終わってましたか。そうでしたか。
          親コメント
    • by akiraani (24305) on 2008年05月21日 15時56分 (#1347728) 日記
      >このようなツールの出力にどう対処するかが問題。

      完成したコードにツールを通したあとで警告を減らすために修正するとけっこうひどいことになりますが、この手のツールに引っかからないようなコーディングスタイルを身に着けるというのはかなり有効ではないかと思います。

      なので、製品のチェックに使用するなら、コーディング工程のかなり早い段階(クロスレビュー前)で使用し、既存のコードへの使用は傾向分析等を主にするのがいいんじゃないですかね。
      これなら、逃げでごまかすよりも、警告の出にくいコードを書くようになると思うんですが。
      --
      しもべは投稿を求める →スッポン放送局がくいつく →バンブラの新作が発売される
      親コメント
      • by whelp (25685) on 2008年05月21日 20時06分 (#1347860)

        静的解析ツールについては組み込み系の中の車両系では普通に用いられています。 使う理由としては

        • 製品に不具合が発生すると最悪人命に関わる自体に発展するおそれがあるので可能な限り不具合を発見したい
        • 人間では検査の質にムラが生じるが、ツールによる自動検査だとムラが生じない(新入社員でも、ベテラン社員でも一定の品質が確保できる)
        などが上げられます。

        特に近年、静的解析ツールに注目が集まっているせいか、ET2007でのチュートリアルセッション( http://www.jasa.or.jp/et/ET2007/conference/info_ts.html#TS-6 [jasa.or.jp])でもアイシン精機の方が講演中で静的解析ツールの導入・活用方法について触れられています。

        私の知っているメーカーでは、静的解析ツールが出力した警告の報告・確認事項・対処(対策)法をマニュアル化して徹底させています。 しかし、静的解析検査はインフルエンザのワクチンのようなもので、一部の不具合の混入を防止するための手段の一つでしかなく、すべての不具合を検出できるわけではありません。 でも、最後は必ず複数の人間でコードレビューを行います。

        また、車両系では製品を欧州に輸出するためには、開発プロセス中でMISRA-Cを用いなければならないようなので、選択したルールを満たしているかどうかの自動チェックにも用いています。

        ツールを利用するタイミングですが akiraani さんが述べられているように、短時間で解析結果が出せるツールを

        コーディング工程のかなり早い段階(クロスレビュー前)で使用
        していますし、ツールによっては統合開発環境(Eclipse/HEW等)に組み込めるので、コンパイルの前にチェックを必ず行わせるようにしています。

        また、検出率が高いが実行時間が長いツールも用いており、こちらは金曜日の夕方に解析を開始させると月曜日の朝のミーティングの前には結果が出ます。 そのため月曜日は検出された問題点に対する対処などを話し合っています。

        ほかに、静的解析の他にもデッドロック発生の可能性やタイミングの正しさを確認するための動的解析環境の利用もマニュアルで指示されており、開発プロセス中でツールを用いるのが当たり前になっています。

        ----

        (中に近い人なので話せる範囲で。)

        親コメント
    • by Anonymous Coward on 2008年05月21日 16時31分 (#1347745)
      組み込みプログラマの吹き溜まり自動車業界には MISRA C という C 言語コーディング上のお約束集があるのですが、こいつに書いてあることのいくつかはどうにも腑に落ちません。
      中でも最凶最悪なのは、関数の途中での return 禁止というものです。
      枝刈りして関数を抜けたいのに、フラグを引き回して入れ子が深くなって読みづらいのです。
      なにが嬉しくて可読性を落とすのか。教えて!エロイひと!

      親コメント
      • 組み込みとかは一行も書いたことはないですが,関数の途中で return 禁止にしておくと防げそうなバグは思いつきます:

        int func()
        {
            lock();
        ...
            if (statement_stands)
            {
                /* ここでロックをはずすのを忘れる */
                return;
            }
        ...
            unlock();
            return
        }

        とか.
        親コメント
      • by Anonymous Coward on 2008年05月21日 17時16分 (#1347764)
        エロい人です。

        MISRA-Cってのは自分で適切なルールを選んで適用するものです。

        ですから、関数途中のreturnを禁止するとうまくない理由をちゃんと説明して
        そのルールを外してもらうのがMISRA-Cのやり方です。
        外してもらえないのなら、あなたの説明が悪いか、ボスand/or顧客がアレなのか、どちらかあるいは両方です。

        MISRA-Cは正しいのですw
        親コメント
      •  終了処理(メモリ開放とか)とかの漏れチェックが容易になるからとかではないかな。
         メモリリークやハンドルリークなんかは場所の特定がたいへんに面倒なので、コーディングレビューで出来るだけ潰しておきたいというのは考え方としてはありだと思うけど。

         クラス使ってるとデストラクタでカバーできるんでかまわないんでしょうけど、組み込みではそうもいきませんし。
        --
        しもべは投稿を求める →スッポン放送局がくいつく →バンブラの新作が発売される
        親コメント
      • by Anonymous Coward on 2008年05月21日 23時15分 (#1347946)
        組み込み系ではないですが、途中 returnが推奨されない職場で

        int func(){
          int retcode = 0;
          do{
            /* ==== 条件チェック ==== */
            if(何かの条件){
              retcode = -1;
              break;
            }

            /* ================
               処理本体
              ================*/
          }while(0);

          return retcode;
        }
        というようなコードがはやってましたね。
        #最初に見たとき意味わかんなくて「このループ必要ないよね」と思ってがしがし書き換えてました。
        親コメント
    • Valgrindの警告を黙らせようとしてエンバグしちゃった [debian.or.jp]のが話題になってましたね。
      --
      署名スパムがウザい?アカウント作って非表示に設定すればスッキリさ。
      親コメント
    • by Anonymous Coward
      >というわけで、このようなツールを使ったからどう、という事ではありません。
      >このようなツールの出力にどう対処するかが問題。
      「素晴らしい洞察」ですな。

      Eclipseなんかのツールを使う人の中には酷いコードを書く人も少なくないけれど、
      新人に適切な対処の仕方を教えるためには、Emacsみたいな単純なエディタを使った
      方が教育効果が高いのかも。
      • by Anonymous Coward
        オイラはメモ帳使ってたなぁ。そのうち、色々試すようになって今のに落ち着いたけど。

        プログラム力とは違うが、自分に合ったツールを見繕う力も必要だと思う。

      • by Anonymous Coward
        Eclipseと醜いコードを書く人の関連性は本当にあるのでしょうか?
        • あると思います。ただし、お尋ねのような意味とは違いますが。

          .

          年をとってもコーディングを続けられる(続けざるを得ない、ではなくね)人たちの多くは「最初の頃からずっと使い続けられているエディタ」である Emacs や vi を使っている人が多いと思います。
          # 私も Final を一時期使っていたが、結局それらは生き残らなかった…

          一方で、若い人たちの多くは Eclipse を使っているでしょう。
          と言うことは、単純に考えても Eclipse 側には「若手が多い」というバイアスがかかります。

          プログラミングもやはり経験値がある程度ものを言いますので、「若手が多い」環境はどうしても品質が下がる、という傾向が出てしまいます。
          コーディングを「できなくなる」人たちと言うのは、レベルが低い側ほど脱落率が高いでしょう。と言うことは、同じ世代のプログラマは年齢が上がるほど、平均レベルが高くなるはずです。

          .

          と言うわけで、20年ほど前に「vi/Emacsなんか使っている奴らのコードは使い物にならん」と言われたのと同じ意味において、今の Eclipse 使いのコードは醜い側に広く分布していると思われます。あと20年もすれば Eclipse よりも便利なツールが現れて新人はみなそちらを使うようになり、きっと言うようになるでしょう。

          『xxxx を使っている奴らのコードは醜くていかん』
          --
          fjの教祖様
          親コメント
          • by firewheel (31280) on 2008年05月21日 22時35分 (#1347932)
            >年をとってもコーディングを続けられる(続けざるを得ない、ではなくね)人たちの多くは
            >「最初の頃からずっと使い続けられているエディタ」である Emacs や vi を使っている人が多いと思います。
            多くかどうかは知らないけど、Emacsを使ってる人はEclipse『も』使ってる人が結構いますよ。

            Emacsを使い続けているのは「最初の頃から使っているから」「慣れているから」などという
            理由ではなく、エディタとしてはEmacsの方が遙かに優れているからです。
            #Eclipseは統合環境である以上はエディタが貧弱なのは当たり前。

            より適切な道具を取捨選択して使った結果、今でもエディタにはEmacsを選択する。
            それだけのことです。

            >と言うことは、単純に考えても Eclipse 側には「若手が多い」というバイアスがかかります。
            あまりに単純化しすぎでは。

            上にも挙げたように、Emacsを使ってる人がEclipseも使っていることが多々あります。
            Eclipseから入った若手でも、(おそらくごく一部ではあるが、)Emacsを使ってる人もいます。
            #中にはずっとメモ帳でやってきて、最近になってやっとEclipseを覚えた
            #『経験豊富な熟練者』もいるかもしれないけど、一緒にやってくのには不安を覚える。

            Eclipseから入り、そしてそれ以外を知らない人の中には、自分では何も考えず、ツール
            が出す指示に従って切り張りする人がいます。それでエラーは出なくなるし、コンパイルも
            通ります。でもそれはプログラミングと呼ばれる作業とは全く異なるものでしょう。

            エディタは(たとえそれがEmacsであっても)何も指示してくれないので、自分で考えない人、
            考えられない人は最初の段階で躓きます。またそれを自分で自覚できます。何が分かって
            ないのかに気付くことが、学習への第一歩です。
            便利すぎる道具は、初心者が学習する時には逆効果になりかねません。
            親コメント
            • by Anonymous Coward on 2008年05月22日 0時52分 (#1347990)

              Emacsを使い続けているのは「最初の頃から使っているから」「慣れているから」などという
              理由ではなく、エディタとしてはEmacsの方が遙かに優れているからです。
              そうは思いません、実際EclipseもMicrosoftのVSも使います、もちろん普通のテキスト編集はEmacsかMeadowです。
              そしてemacsもVSもマクロガリガリ使いますし、Eclipseに至っては独自のプラグインも作ります(それがマクロと同じ意味だから)

              ここが肝心な点ですがキーバインドは全部Emacsなんです、要するにアタマで使う部分(機能)と体が覚えた部分(キーバインド)ってのは別の話なんです。(VSのキーバインドをemacsにするためにxemacsから全面的にマクロを使って割り当て直しにしたせいでVS2003,2005,2008と全部個別に対応する羽目になったけど)

              #他人が自分のVSを使うとパニックになるように、僕がまっさらのVSを使うとプリンターダイアログが

              親コメント
            • この手の反論が忘れいているのは 統計とは「も」を考慮してはいけない学問である という点でしょう。

              多数こそが全体の傾向を決めるのであって、「例外」が少々いても、全体の傾向には影響しない。

              # Emacs が優秀である? 知ってるよそんなの。
              # しかし、それでも Eclipse 使いの大半は Emacs 使い「ではない」のだよ。
              --
              fjの教祖様
              親コメント
    • by Anonymous Coward
      とあるデーモンがcoreを吐くと顧客から指摘されて、「では、ディレクトリの書き込み権を削除します」と対応した自称スーパーハッカーがいたなぁ・・・
      今、そのシステムはインフラの一部としてまだ稼動しているようです。

      # さすがにAC。
      • by Anonymous Coward on 2008年05月21日 16時57分 (#1347757)
        自称ハッカーは困ったもんだねぇ、うん。 俺ならそのディレクトリに core って名前のディレクトリ作って回避するけど。
        親コメント
      • by Anonymous Coward on 2008年05月21日 22時47分 (#1347935)
        仕事としてシステムを開発する場合は、プログラムの「美しさ」だけでなく「コスト」も意識すべきです。
        少なくとも「美しくない」=「間違い」ではありません。

        顧客の「デーモンがcoreを吐く」という要望に対しては
        - 美しいが高コストな方法: デバッグ、ソースコードの修正を行い、coreを吐かないようにする
        - 美しくないが低コストな方法: coreを吐いても、coreファイルを保存しないようにする
        という感じで、複数の選択肢があります。

        ここで後者の低コストな方法で顧客が満足してくれるのなら、何も問題はないと思います。

        # 本来は、ちゃんと顧客に複数の選択肢があることを説明した上で、どちらか一方を提案するべきですが。
        親コメント
        • 同じ事を逆向きに言っているだけではあるのですが。

          少なくとも「美しくない」=「間違い」ではありません。

          これはあちらこちらで何度も聞くが、じゃぁ「間違っていないコード」を見るとたいてい「美しい」。

          醜いコードが醜くなるのは、例外の固まりになるから。そして例外だらけのロジックは大抵煩雑で(複雑ではなく煩雑で)、人間の誤りを誘発する。しかも例外ケースは滅多に走らないため、『動いているシステム』であってもバグを内包したままである確率はきわめて高い。

          もちろん、そのようなコードが「あとどれぐらい使われるのか」によっては、直すコストより放置して問題が起こったときに対処するコストの方が安い(期待値として)と判断されるかもしれない。しかし、それは「障害対策コスト」と「障害発生確率」から算出されるべきであって、

          『醜くても動いているんだからいいじゃん。直すのにコストかかるし』

          は、さすがによくない。
          --
          fjの教祖様
          親コメント
      • by Anonymous Coward
        ・客が、明らかに想定以上の(ライセンスで許可されている以上の)データを食わせてた
        ・処理に失敗するのはかまわないが、ディスク容量を食うのは困るらしい
        という条件の下で似たような対処をやったことはある。
        #開発部に上げても「要求仕様に沿ってない状況での不具合には対応する必要はない」という
        #回答しか返ってこないし。
  • by Anonymous Coward on 2008年05月22日 0時11分 (#1347977)
    静的プログラム解析ツールというのは
    「ダメダメな人にでも使わせるとダメダメなプログラムがそれなりの出来になるツール」ではなくて、
    「それなりの人に使わせることでそれなりなプログラムがなかなか良い出来になるツール」なのでしょう。
    「すごい人に使わせてもすごいプログラムが完璧なできになるツール」でもないと思います。むしろこの場合は、ツールの出来によっては「見当はずれな警告しか出ないでストレスの元にしかならないツール」であるかもしれません。

    「こーんなヤツにこんなツールを使わせても役には立たないよ!」という話ばかりでなく、

    実際、次世代静的プログラム解析ツールを導入することで開発方法やテストサイクルに変化はあるのだろうか? 新しい解析ツールは既存のものよりそんなに実力が違うのだろうか?

    こちらの話も聞きたいのですが。「甲のツールを使っていたらこんな警告が出て、こんなバグを見つけたよー」とかいう話もよろしく。
    • by Anonymous Coward on 2008年05月22日 2時53分 (#1348026)
      使っているツールの名前は出しませんがなかなか優秀だと感じました。
      ごくまれに、なんで警告が出るんだ出るわけないだろってこともあります。

      警告の内容は例えば
      1.int型に対しビット演算を行うと「整数型に対してビット演算を行っています」ってな感じの警告が出ます。
        この場合unsigned int型でビット演算を行えば警告は出ません。

      2.もしchar型の範囲が-127~128だった場合
        0xffを代入しようとした場合これも警告が出ます。
        型の範囲外の値を代入しようとしているためです。
        charの範囲は環境により異なるためなんともいえませんが。

      3.short型(16ビット)にint型(32ビット)の変数を代入させた場合「暗黙のキャストが行われます」とか出ます。
        この場合、short型にキャストするれば警告が消えます。short型の変数に入れて良いかもチェック巣r必要も出てきます。
        ただ、int型(32ビット)にshort型(16ビット)の変数を代入した場合は警告は出ません。
        (ほかのツールなら警告が出るかもしれませんが)

      4.unsigned int型のiに対し
        
          for(i=100;i>=0;i--)
        
        なんて書いた場合も警告が出ますね。「for文の条件は常に真です。」といった内容だったかと。

      5.  int data;
          char tmp = 5;
          data = tmp << 16;
        
        これも警告が出ます。警告の文面は忘れましたが
        tmpの型の範囲外へシフトを行っており情報が失われる。だったかな?
        tmpは最大8(7?)ビットしかシフトできないためです。
        この場合
        
          data = ((int)tmp) << 16;
        
        とすればよかったと思います。

      6.  #define AAA(data,val) val = data
        
        これも警告が出ます。
        
          #define AAA(data,val) (val) = (data)
        
        とする必要があります。

      7.  #define BBB(data1,data2,val) \
          { \
          (data1)=(val); \
          (data2)=(val); \
          }
        
        この警告は「valは2度以上使用されます」といった内容だったかと。
        
          BBB(a,b,c++);
        
        と書いた場合cが意図していない内容になるかもしれないためだと思います。

      もっと深い警告もありますが今手元にデータが無いので内容覚えてません。
      かなりうろ覚えなため間違ってるかもしれません。
      そもそも「こんなコード書くなよ」といわれればそれまでですが。
      親コメント
    • FindBugsは無料ですよ。Java用なのがアレですが。

      こいつ、最初に使ったとき、コードレビューで見逃していてテストでも検出できなかったヌルポな可能性をサックり出してくれて感心しました。
      また、表現の揺らぎなんかも検出してくれるのがうれしいですね。

      class A {
          public void setID(String id) {} // 「L B Nm: A.setID(String) と B.setId(String) のメソッドは、混乱しがちです。」と警告
      }
      class B {
          public void setId(String id) {}
      }
      また、JDBCを使って直接DBを叩いているなら、文字列結合でSQLを作成している部分を探してくれたり、servletにフィールドを作っているコードを検出したりと、自分のミスだけでなく他のメンバーのコード管理にも有効に使える代物ではないかと思います。
      Javaで開発をしているなら使わない手はないと思うのですが、周囲ではなぜか少数派です…。

      弱点があるとするなら、項目の有効無効設定の単位が少し大雑把なもんで、適用除外をする場面が出てきてしまって少々面倒なルール記述をしなきゃいけなくなる場合があるってところくらいだと思います。
      親コメント
  • by Anonymous Coward on 2008年05月21日 13時39分 (#1347650)
    lintで充分
typodupeerror

長期的な見通しやビジョンはあえて持たないようにしてる -- Linus Torvalds

読み込み中...