謎の変数「flag_a」に触れた瞬間、システムが崩壊したあの日
組み込みエンジニアとして現場に出れば、必ず一度は遭遇する「開けてはいけないパンドラの箱」。 それは、**「誰が書いたか分からない、仕様書もない、でも10年間なぜか本番環境で動いているC言語のスパゲティコード」**です。
「このUIの表示タイミング、ちょっとだけ変えといて。すぐ終わるでしょ?」
上司からの軽い依頼。あなたはソースコードを開き、該当しそうな処理を見つけます。 そこには、意味不明な名前のグローバル変数が鎮座していました。
if (flag_a == 1 && cnt_b > 10) { ... }
「なんだこの flag_a って? まあいい、この条件を少し変えればUIの挙動は直るはずだ」
そう思って数行のコードを書き換え、コンパイルして実機に焼く。UIの表示は完璧に直りました。 「よし、ミッション完了!」と安堵したのも束の間、テストチームから血相を変えて電話がかかってきます。
「おい! なぜかモーターの非常停止が効かなくなってるぞ!! 暴走してる!!」
血の気が引く瞬間です。 必死にコードをgrepして追いかけると、なんとその flag_a は、タイマー割り込み処理の中でモーターのパルス制御のオンオフ判定にも使い回されていたのです。しかも、extern 宣言で5つもの別ファイルから参照・書き換えされながら。
「どこを直せば、どこが壊れるか全く分からない」
この恐怖を抱えたまま、当てずっぽうでコードを弄るのは、目隠しで地雷原を歩くようなものです。「触るな危険」と言い伝えられてきたレガシーコードの保守・機能追加を押し付けられたとき、私たちに必要なのは「度胸」でも「長時間の残業」でもありません。
この記事で得られること
本記事では、「ドキュメントなし・グローバル変数まみれ・巨大な1ファイル構成」という最悪のレガシーC言語コードに対し、**新たなバグ(エンバグ)を絶対に生み出さずに改修を行うための「3つの安全手順」**を解説します。
【有料部分の目次】
-
- 修正前に絶対やるべき防波堤:ハードウェアに依存しない「単体テスト環境」の作り方(モック化)
-
- スパゲティを解きほぐす:巨大なswitch-caseやネストの深いif文を「関数ポインタ」で安全に切り離す
-
- 見えない地雷を可視化する:Doxygenとgrepを使った、グローバル変数の「影響範囲」特定術