プログラムが水曜日にのみクラッシュしたとき

落ち着いてリラックス-私のお気に入りのバグについて話しましょう。



これは、IT分野での私の最初の仕事でした。非常に深刻な医療機器、特に麻酔 患者の 搬送システム入院患者用のモニターを開発している会社での夏の練習です。 患者用モニターは、脈拍、圧力、呼吸数などを測定し、トラブルが発生した場合に看護師に通知するベッド患者の隣にある鳴き声の箱です。 オフィスには笑いガスのある2メートルの風船がいっぱいで、組み込みシステムの豪華なひげを生やした専門家が歩き回り、特にさまざまな機器の認証に必要な文書のための保管室全体がありました。 人々はまだ、十数年前にテスターが見逃していた1つのバグについてささやいており、それが手術の途中で麻酔デリバリーシステムを再起動させました。 言うまでもなく、私のような緑色のジャーク学生は、1キロメートルの戦闘システムに行くことを許可されないでしょうか?



代わりに、1997年の最もホットな技術革新のテストを目的としたプロトタイププロジェクトを委託されました。シリアルポートでモニターをリッスンし、興味深いデータをSQL Serverデータベースにマージし、CORBA経由でJavaアプレットに送信するC ++サーバー医師と親relativeは、インターネットを介して患者の健康を監視できます。 美しさは同じです! 特に、これらのシステムやテクノロジーのいずれも実際に使用したことがないことを考慮してください!



主にVisibroker ORBマニュアルの喫煙と退屈なタイプキャストエラーのキャッチに費やされた地獄の松葉杖の数週間後、私のSimpsonシステムは多かれ少なかれ準備ができていました。 ホーマーサーバーはデータを保存および発行し、Bartクライアントはそれらをユーザーに表示しました。 この間、CORBAはすぐに使える状態であり、AWTはtin( GridBagLayout



、brrr!)であり、アプレットはカタツムリの速度で動作しますが、Javaは優れた言語のようです。 1つのマイナーなバグだけが気になりました-C ++サーバーがクラッシュすることが時々あったので、その理由を突き止めることにしました。



隣の部屋に実際のモニターを備えたテストベンチがあったので、開発とテスト中に、非常に便利な「デモモード」を使用して、心臓発作の模倣を円で楽しく再現しました。 このモードでは、サーバーがクラッシュすることはありません-モニターの手動制御中、特にショー中にクラッシュすることがありましたが、割れても、安定した障害再生を達成できませんでした。 すべてのイベントにログを追加し、モニターと職場の間を行き来し、ゆっくりと思慮深く必要なステップを再現しました(「フィルターをXに設定し、コントロールノブを時計回りに3目盛り正確に回して、ここをクリックしてください...」)が、ドロップしません再現。 この「邪悪なイベント」が何であれ、私がそれを呼んだように、それはロギングを避けました! たぶん問題はI / Oまたは鉄のレベルにあったのですか? たぶん、宇宙線は私のコンピューターの記憶の中のビットを落としましたか?



数週間の実りのない実験により、私は完全に必死になりました。 シリアルポートからデータを受信して​​データベースに書き込むまでのコード行ごとにprintf



出力を追加するようになりました...その過程で、これらの各行を何度も見て、突然私に気づきました。



データベーススキーマについて説明したとき、スペースを節約しようとする不可解な試みで、私は愚かさと幼児期を使用して、 timestamp



イベントを主キーとして使用しました。 2つのイベントが同じミリ秒で到着した場合、ベースは一意性違反の例外をスローします。 私はこれを非常に早期に発見しましたが、これは非常に奇妙な場合にのみ発生する可能性があると考えました。誰かがモニターの内部設定を掘り下げ、明確な良心でこのコードをtry/catch



でエラーロギングでラップしました。



しかし! ログコードはオールドスクールスタイルで記述され、エラーテキストは80文字の文字列バッファーに書き込まれました。 キーの一意性の侵害に関するメッセージは常に同じでしたが、次のように、英語の拡張形式の日付が先行していました。



Monday, July 17, 1997, 10:38:47.123









英語の曜日の名前には面白い特性があります。

役職 文字の長さ
日曜日 6
月曜日 6
金曜日 6
火曜日 7
木曜日 8
土曜日 8
水曜日 9
すでに推測?



水曜日に、水曜日にのみ 、誰かが特定のモニター設定を特定の方法で変更すると、2つのイベントが同時に発生し、データベースでクラッシュが発生する可能性がありました。 また、エラーメッセージの長さは正確に81バイト(ヌル文字を含む)で、バッファをオーバーフローさせ、システム全体がクラッシュしました!



それ以来、3つのことを学びました。 まず、必要なテーブルで常に自動インクリメントの主キーを使用します。 次に、日付を曜日なしでISO形式YYYY-MM-DD



で記録します。 しかし、最も重要なことは、最もランダムで予測不可能なバグであっても論理的な説明があり、十分に深く掘り下げると発見できることです。



All Articles