建立!デバッグ神社

こんにちは~、アドグローブ ソリューション第2事業部の岩浅です。
普段はウェブアプリのサーバーサイド機能を作ったりなどしております。

ほとんど自社にいない私なので、せっかくの機会に技術力アピールできるかっこいいことを書きたいな! 新技術!便利ツール!リッチなUI!社内コンテスト!凄い!いいな!そういうこと書きたい!

と思ったんですが、残念ながら私のネタ(技術力)は...ネタが.....何もない...。
…まあ、ないものはしょうがないです。この程度でもまあまあエンジニアとして生きていけますよ、という低い方の安心感をご提供いたします。

というわけで、キャッチーそうなタイトルで適当なことを書き散らします。タイトルから考えました。
内容は完全に初心者向けで、主にサーバーサイドの話をします。フロント側の話ですとか、さらには便利なデバックツールみたいな話はわからないのでいたしません。

デバッグの対象

デバッグというと何やら専門的ですが、つまりはプログラムの問題潰しです。
プログラムの問題とは何か、というとおおむね以下の2つだと考えています。

  • 思ってたのと違う動作
  • 意図せぬエラー

問題を見つけた後の [技術的な解決提案]⇒[現実的な落としどころの決め / 修正]⇒[リリース]の方が時間を取られることが多いですが、 何しろお客様との調整や仕様確認などのやり取りも大きく関わってきますので、ここでは取り上げません。
今回は技術屋さんが確実に提供できる問題の発見と解析に焦点を当てていきます。
 

思ってたのと違う動作って何よ

何でもです。

通信先でも、ボタンの位置でも、DBの登録データでも。プログラムはすべての動作が意図通りになっている必要があります。
意図ではなくて仕様じゃないのと思ったそこのあなた、その通りです。その通りなんですが、実はきっちり仕様が決められているかというと案外そうでもなくて、絶妙な隙間に落っこちてしまうことが多々あります。仕様とは....。しょうがないので、こういう動きをするはずですよね?しないんですけど直していいですね、とこちらからやりやすいよう押していきましょう。

見た目は動いているように見える以上、この問題に気が付くのが非常に難しいです。たぶん根本的にはテスト設計の話なのでしょう。

まずは、仕様書から起こせるパターンを網羅します。この辺りはまだ考えやすい。
それから、システムを初めて使う人、昔ながらのやり方を無理やりねじ込もうとするベテラン、人の話を聞かない人、必ず最悪の事態を引き当ててしまう凶運などあらゆるタイプになりきって対象のシステムを眺めてみます。このシステムをいかに無茶苦茶に破壊できるかと考えてみます。こういうこともあるかも、という新しい観点が出てきます。

または、シンプルに他の人の意見を聴けるならそれが一番いいです。
こうしてひねり出したすべての観点についてinputと想定されるoutputを正確に並べて、テストしていきます。

想定したoutputと実出力の比較をするのに、目視だと絶対に見逃すのでシステムとして一致不一致を確認できるといいなぁと思いますが、今まで手作りツールにしか出会ったことないんですよね。
便利ツールとかの知見があったら知りたいです。どなたか書いてください。なにとぞ。

エラー

これはわかりやすい、目に見えて対処しなければいけないものです。
運用中に出てくるとタイムアタックの上に切腹が待ち構えているのでつらいですが、エラー解析自体は謎解きっぽくて面白いですよね。そんなことないですか?..そう。

エラーもその場ですぐ出てくれるエラーと、特定の条件下でのみ発生するエラーがあり得ます。
私もつい先週、カウントが127を超えたらエラーが発生するというバグを仕込まれたプログラムにぶち当たり、コーヒーをこぼしました。
特定の条件下でのみ発生するエラーを見つけるのは難しいですが、パターンテストを頑張る以外の対応として、バグのチェックツールなんかが活用できるかもしれません。
javaの場合は SpotBugs(findbugs)みたいな。エラーになるぐらいなので、仕様に関係なく機械的に見ても危うい記述になっていたりします。

エラーログの読み方

せっかくなので、エラーログの見方についても簡単にご紹介しましょう。
慣れないうちは、どわどわ流れてくるのをみて物量に困惑するばかりだと思います。
が、実は大半は見なくていいものです。今どきのフレームワークでいっぱい包まれているだけで、欲しいのは2~3行だったりします。
謎のエラーを人に相談すると、エラーログ全部くれと言われたり、余分なもの入れるなと言われて混乱するかもしれません。
その心はというと、この数行が手に入れば全部はいらないし、逆にこの数行が含まれていなければ特定できないので前後も含めて全体を見たいということです。

エラーログとしてみるポイントは、一番上に出てきたエラーメッセージ(全文)と数行~十数行下に表れているであろうのエラー発生個所情報です。
さらにここにたいていのログで決まったフォーマットで出力しているであろう時間情報も加えると、5w1hのうち「何が(what)、どこで(where)、いつ(when)」3つがわかります。

具体的な例を挙げてみるとこちらです。

ひょいっとエラーを出してみましたが、長くてめんどくさくなったのでクリックしない方がいいです。画面に見える範囲を画像に切り出すとこんな感じです。

時間とエラーメッセージは見つけやすいですね。発生ポイントをどこから探すかというとパッケージとクラス名でざっくり見ていきます。
javaやorgといったフレームワーク側はバッサリと無視して、「jp.dummy.tekito~」のような自分たちで作成した見慣れたパッケージのものにだけ集中します。

1行目 エラーの発生時間 : 2022-11-08 17:32:31.316
3行目 エラーメッセージ:「No message found under code 'happy.things.today' for locale 'ja'.」
5~16行目 エラー発生個所:LocalizedMessageSource#getMessageメソッドがエラーのポイントですが、HistoryServiceのfindAllById、getEventNameを呼び出す流れで発生したということもおさえておくといいでしょう

今日の幸せが見つからないというエラーでした。
ここまでわかればログの調査としては十分です。特定した該当ソースを見たり、動かしたりしながら、誰がやっても発生するのか(who)、どのように(how)発生するのかを特定しましょう。 原因(why)まで推測できればいいですが、まずは状況が分かった時点で責任者に報告し、どのように解決していくかを相談しましょう。

実は追いかけても何もつかめないエラーメッセージもままある

HTTP status Error 418 I'm a tea pot
https://www.google.com/teapot

基本的にはエラーメッセージから「何が発生したのか」を探っていくのですが、たまに見当はずれなメッセージでグーグルの奥地に迷い込んでしまうことがあります。
メッセージをググってすぐにピンと来なければ、先に自分のプログラムのどこで問題が発生したのか切り込んでみるほうがいいかもしれませんね。問題箇所が特定できれば、そもそも何をやろうとしているポイントなのかがわかるので、メッセージそのものはそれほど重要ではなくなったりします。英語のメッセージの解析とかに2時間も3時間も使うことないんだよ..。

まとめ

だらだらと書きましたが、実はデバッグを進めるうえで最も大事なことは、「人に聞く、人に説明する」だと思います。
問題箇所の特定に30分以上悩むようでしたら、それはもう解決のための手札が足りないのです。
実務で取り扱うプログラムについて、仕様・技術のすべてを完璧に把握できることなどほとんどありません。
自分の知識では足りない部分、そもそも発見されていなかった要因など一人で悩んでもどうしたって手に入らないものが重要なポイントとなりえます。
実力の問題ではなくて、使える手札の問題ですね。問題の解決策は自分の想像の世界には決して存在しません。他の人の手札も使わせてもらいましょう。

エラー解析中、テスト中、問題箇所が分からない時はデバック神社を建立してPCに貼り付けましょう。

▼神社の作り方 orikata-app.com www.origami-club.com テレワークの場合は、チャットに写真を流してアピールしましょう。見た人は助けてください。

どんどん神社を建てていきましょう。
最後までお読みいただきありがとうございました。



現在アドグローブではエンジニアを含め、さまざまなポジションで一緒に働く仲間を募集しています。
詳細については下記からご確認ください。みなさまからのご応募お待ちしております。

hrmos.co