トラブルシューティングの極意―達人に訊く問題解決のヒント

第11回 [ソフトウェア開発編]むやみやたらにデバッグ+テストしていませんか?―「ソースコード」の指紋からわかるバグの原因

この記事を読むのに必要な時間:およそ 3 分

ソースコードリーディング技術によるバグの見つけ方(上級編)

[方法3]内部の兆候検知(特異記述の検出)

「コード開けたら1行目からいきなり読むな」はコードリーディングの鉄則です。何らかの兆候を示しているソースコードを見つけたら,エディタ上でも検査対象を絞り込みましょう。

バグのキスマークを探せ!

例外処理ブロックが存在し,エラーを捕捉するところまではできていても,実は例外処理が空,すべてコメントアウトされている個所も少なくありません。

例1

} catch (Exception e) {
}

例2

} catch (Exception e) {}

これを「例外処理の握りつぶし」と言います。これは例外設計が不十分であることを示唆します。これを発見するには,次の正規表現を使います。

  • {}または{\s+}

Javaならば,catch ( Exception e ) {}のように例外未実装の個所を特定します。該当個所があれば,それは例外処理が未実装です。機能追加を依頼しましょう(たとえばデバッグコードを挟むだけでも,ログを吐かせる一文だけでも!)⁠

この「{}」は,見た目が唇の形に似ていることから,俗にキスマークと呼ばれます。一般的に頻出する欠陥・バグの類(たぐい)です図5)⁠色恋にかまけて「大切なことを忘れる」という意味ではありません。

図5 キスマークの原因(多くの場合「時間制約」が原因)

図5 キスマークの原因(多くの場合「時間制約」が原因)

セミコロンだけの行を探せ!

一般的なオープンソースの静的解析ツール(例:JavaであればFindbugsなど)を用いて品質検査を行った場合,⁠例外処理ブロックが空です(empty catch block)⁠といった指摘が出ることがあります。

前述のキスマーク未実装などは,これに該当します。ところが,開発途中のコード(とくに初期開発や,例外処理実装失敗に起因するコード更改などの場合)には,⁠ブロックの内部にセミコロンを挿入」してツールを黙らせることがありますリスト1)⁠

リスト1 セミコロンだけの行があるぞ!

} else {
  try {
    //log.debug( "REMOVE_SESSION--->" + paramString);
    // その他操作の場合,Sessionに値があれば削除する
    this.session.remove(paramString);
  } catch (Exception e) { 
      ;   ←これ何?!
  }
}

つまり,セミコロンが挿入されることで「命令行が存在する=空ではない状態にする」という方法です。これも,

  • ^(\s+¦\t+);

といった正規表現で簡単に検出できます。

これは「悪質な手抜き」の1つです。意図的にツール指摘を回避することは,本来のツールの意味を無に帰すばかりでなく,後続工程や将来のデバッグを極めて困難にする可能性が高いからです図6)⁠

図6 ⁠例外の握りつぶし」または「怠慢」

図6 「例外の握りつぶし」または「怠慢」

筆者は,このキーワードが出たソースコードについて,全行をチェックします。ほかにも実装誤りやツール指摘回避が行われていないか徹底的に目視検査をします。

「はず/かも」チェック

これは「はず」⁠かも」というNGワードを,全コードに対してgrepコマンド実行をします。これら表現が含まれるコードは,必ず目視対象として重点検査します。とくに次の場合に有効です。

  • 期待値と異なる
  • 機能更改後
  • 保守後

原理は簡単です。ソースコードの特定のブロック文の中に「はず」⁠かも」という日本語キーワードを探すと,

  • 「ここには制御が到達しないはず」
  • 「今後変更されるかもしれない」
  • 「暫定対応」

といった開発者の「未確定」⁠自信がない」ことを示すコメントが出てきます。この前後コードは必ず確認しなくてはいけません(ヒドいものになると「苦肉の策」というコメントにも遭遇します)⁠これらの記述に関しては,もちろん該当個所を詳細に分析し,暫定対応を恒久化する必要はありますが,それ以上に,当該「未確定」個所の混入理由を分析することで得た教訓を再発防止に使いましょう。

おわりに

コードが示す兆候の利用とその対策・効果は,必ずしもすべてのプロジェクト・プログラムに適用できるものではないかもしれません。しかし,本稿のアプローチで,完全網羅にこだわった人海戦術のムダなテスト実施を避けることができ,デバッグ速度を圧倒的に向上させることができます。

筆者は,さまざまな技法や手法を(工数をかけて)大量に実施し,網羅的にテストでバグを出す手法をあまり好みません。大量テストの実施が目的でない限り,テストケースは少ないに越したことはないはずです。国内市場は開発量が飽和点を迎え,産業としての保守・維持が主要課題になっています。トラブルを未然に防ぐ品質エンジニアの育成が急務です。全部テストしきれないほど複雑さが増加し,いわゆる「手が付けられない状態」を打破するためには,このようなメトリクスを駆使する「センス」を持った「品質エンジニア」が求められています。本連載を起点に目指してみませんか!

Software Design

本誌最新号をチェック!
Software Design 2019年7月号

2019年6月18日発売
B5判/192ページ
定価(本体1,220円+税)

  • 第1特集
    ⁠速い⁠Webアプリケーションの作り方[バックエンド編]
    ボトルネックの見つけ方,キャッシュ・CDNの活用
  • 第2特集
    IT業界ビギナーのためのDocker+k8s入門講座[Kubernetes編]
    図解で深く理解して最先端にキャッチアップ!
  • 特別企画
    完全マネージ型のメリットを堪能する
    Amazon SageMaker入門
  • 特別企画
    クラウドへのルータ接続実践ノウハウ
    【2】AWSとヤマハルータをつなぐ
  • 一般記事
    「WebAuthn」が導く新時代のパスワードレス認証
    【後編】WebAuthnを利用したFIDO導入のための考え方
  • 短期連載
    Mattermost[導入+構築]入門
    【最終回】ご存じですか? chat導入のメリット

著者プロフィール

細川宣啓(ほそかわのぶひろ)

日本アイビーエム株式会社東京基礎研究所 所属

品質エンジニアリング・欠陥エンジニアリング。バグ収集,特に集めたソフトウェア欠陥を眺めてバグ百科事典の編纂。

最近は人工知能やIoT,ロボットの品質保証について考える日々です。

https://www.facebook.com/nobu.dreamstate.hosokawa

バックナンバー

トラブルシューティングの極意―達人に訊く問題解決のヒント

バックナンバー一覧