これまで見た中で最も奇妙なバグ
(engineering.gusto.com)奇妙なバグの発見と解決の過程
- 内部ツールチームのオンコール対応中に、Gusto の内部ソフトウェアを使うユーザーが Chrome ブラウザのクラッシュを経験した。
- この問題はカスタマーサービスにさまざまな支障をもたらした。
- 問題解決のために、経験豊富な同僚、プロダクトインフラチーム、IT チームの支援を受けた。
最初の手がかり
- 影響を受けたユーザーに共通点がないか探した。
- すべての Gusto 社員が影響を受けたわけではなく、顧客向けソフトウェアには問題がなかった。
- 他の内部ソフトウェアの Web ページは正常に動作した。
- クラッシュは一貫性なく発生し、Safari や Firefox では問題が起きなかった。
2つ目の手がかり
- Chrome のバージョンが問題かもしれないという仮説を立てた。
- 一部のユーザーは Chrome のバージョンを更新すると問題が解決したように見えたが、完全には解決しなかった。
- Chrome 拡張機能が原因かもしれないと推測したが、拡張機能なしでも問題は再現した。
バグ再現の難しさ
- インフラチームが全エンジニアに問題の再現を依頼した。
- トルコの 2 人のエンジニアを除き、エンジニアチームからはクラッシュの報告がなかった。
- Chrome のクラッシュレポート機能がセキュリティ上の理由で無効化されており、問題解決は困難だった。
幸運な転機
- デンバーのあるエンジニアが、Grammarly のデスクトップアプリをダウンロードした後に問題が発生したと報告した。
- Grammarly アプリを削除してコンピューターを再起動すると問題が解消することが分かった。
進展
- デバッグが可能になると、原因を特定するためにさまざまな試みを行った。
- 主要な内部アプリケーションは ActiveAdmin を基盤に構築されていたが、React を使う新しい部分ではクラッシュしなかった。
- 共通コード部分を調査する中で、
My Historyのドロップダウンメニューが原因であることを突き止めた。
問題解決
loader-spinner.gif画像ファイルが問題を引き起こしていることが確認された。- その GIF を別の画像に置き換えると、ページはそれ以上クラッシュしなくなった。
- Grammarly か Chrome のどちらかが問題を修正したのか、今では元の GIF でも Chrome はクラッシュしなくなっている。
結論
- 予想外のアニメーション GIF がデバッグの答えだった。
- 好奇心と協力によって問題を解決した。
- Gusto では、協調的で好奇心旺盛な人々と一緒に働ける機会がある。
GN⁺ の意見
この文章で最も重要なのは、予想外の原因によるバグを発見し解決するまでの過程が詳しく描かれている点だ。ソフトウェアエンジニアリングの複雑さと予測不能さを示すとともに、チームワークと粘り強い問題解決力がいかに重要かを強調している。エンジニアリングチームがどのように協力して難解な問題を解決するのかを示す興味深い事例であり、この分野に関心のある人にとって非常に魅力的な話になっている。
1件のコメント
Hacker Newsのコメント
読みながらGrammarly関連の問題ではないかと思ったが、以前にも似たように再現はできないものの、特定の部署内の多くの人に影響するバグに遭遇したことがある
結局の共通点はGrammarly拡張機能のインストールで、本番サイトではなくステージングのプレビューURLでのみ発生していた
原因はGrammarly拡張機能の誤った正規表現で、ドメイン名が約100文字を超えるとページが停止した
今回の件が本当にデスクトップアプリのせいで起きたのだとしたら、さらに恐ろしく感じる
多くの問題は特定の組み合わせまで絞り込めても、肝心のなぜそうなるのかが分からないと満足できない
それで今は正規表現エンジンを読んでいる: https://swtch.com/%7Ersc/regexp/regexp1.html
Windows 10の全社アップグレードの過程で、あるマネージャーの古いノートPCを交換したのだが、ソフトウェアとネットワーク要件の確認、ユーザープロファイルと文書のバックアップなど、手順はしっかり整っていた
機器評価表には10年物のThinkPad、RAM 4GB、電源ケーブルを抜くと落ちるというメモがあり、それを頼りに使い続ける忍耐力はすごいと思えた
新しいノートPCを配布した後、ほぼすべて正常だったが、Grammarlyのライセンス移行だけができなかったため依頼を出し、1週間後にライセンスキーが適用されてGrammarlyも正常だと確認された
ところがその日の後になって、セキュリティカメラのWebページがクラッシュするという連絡が来て、ヘルプデスクが再起動、キャッシュ削除、ブラウザ再インストール、プロファイル再作成まで試したが解決せず、私のところに回ってきた
ネットワーク、ファイアウォールログ、別のPC、現地/外部アクセスをすべて確認したが、私の側ではすべて正常で、他の人にも問題はなかった
「最近PCやオフィスで何か変わったことはありますか」と聞くと、冗談めかして「今日Grammarlyを入れたので、それですかね」と言われ、アイデアが尽きていたので本当に削除してみたところ動いた
再びGrammarlyを有効にしてリンクを押すと、確実に失敗した
そのカメラソフトウェアは非常に古く、カスタムホームページのリンクは非常に長いPHP生成URLのような形で、現場でGrammarlyを使っていたのはその人だけだったため、一度しか見られなかった問題だった
開発者は拡張機能が原因かもしれないという発想をしばしば見落とすが、拡張機能はWebページにありとあらゆることをしうる
大学の教授が論文を書いていて、下線が維持されないと言うので、単なるユーザーの操作ミスだと思い、5分もあれば手伝えるだろうと思っていた
しかし3時間以上たってようやく、特定のビデオカードドライバのバージョンと特定のプリンタドライバのバージョンの組み合わせが、下線の印刷だけを妨げていることを突き止めた
https://www.zdnet.com/article/xerox-scanners-alter-numbers-i...
クラッシュレポートを無効にしていても、ユーザープロファイルディレクトリのどこかに**.dmpファイル**が生成されている可能性がある
そのファイルをhttps://crbug.com/newのバグ報告に手動でアップロードすれば、Chrome開発者がデバッグできる
クラッシュレポートを無効にしたのと同様の理由でダンプを共有できないなら、Chromiumで
minidump_stackwalkをビルドしてシンボルなしのスタックトレースを作成し、バグ報告に添付できるそうすればChrome開発者がシンボルを適用できる
詳しくはhttps://www.chromium.org/developers/decoding-crash-dumps/にある
このバグを生んだ技術の組み合わせが興味深い。2023年のWebはまさにこういう姿だ
Chromiumのバグが解決済みなのか知りたいが、この一覧をたどるのは簡単ではない: https://bugs.chromium.org/p/chromium/issues/list?can=1&q=gif...
Gustoが「うちのせいではなかった」と示しつつ、Grammarlyを少しだけいじるためにこの記事を載せた感じなのも良い
Linuxで起動したあと、ときどき音が出ない問題があったが、調べてみると Windowsとのデュアルブート 設定が関係していた。
Windowsから再起動すると、Realtekのオーディオデバイスが完全にはシャットダウンされず、省電力状態のままになり、Linuxがそのデバイスを初期化できなかった。
解決策は、Windowsでは常にシャットダウンしてから電源ボタンで起動することだけで、問題自体はまだ残っている: https://askubuntu.com/questions/1032543/no-sound-in-ubuntu-1...
WindowsとLinuxをデュアルブートしていた人が、Windowsで起動したあとにLinuxへ再起動したときだけWi-Fiが動作していた。
LinuxのインストールにWi-Fiカード用の ファームウェアパッケージ が入っておらず、Windowsから再起動するとデバイスがすでに準備された状態になっていたが、Linuxへ直接コールドブートするとだめだったということだ。
結末が完全に肩透かしだという点には同意する。
ChromeのソースコードにもGrammarlyのソースコードにもアクセスできないので推測しかできない、という話だが、これが「オープンソース」運動のもたらした結果なのかは疑問だ。
ソースコードがないと完全にお手上げで、それ以上深掘りするのを拒む開発者が生まれているわけで、真実を知られたくない企業にとっては、そういう姿勢は非常に都合がいいだろう。
以前はソースがなくてもプログラムを 逆アセンブル して理解し、パッチを当てる人が大勢いて、そのかなりの数は職業開発者ですらなかった。
ただソフトウェアを自分の望むように動かしたいという動機があり、その過程で必要なだけ自然に学んでいった。
この記事は、スタック全体の複雑さが狂気じみているという点にも触れている。フレームワークの上にさらにフレームワークが積み重なっているのを見ると、そのかなりの部分は自業自得にも感じられる。
loader-spinner.gif、つまりメニューオプションの読み込み中に表示するプレースホルダーを削除したらページのクラッシュが止まったというが、そもそもメニューオプションの読み込みにアニメーションが必要なほど時間がかかるのかも疑問だ。ソフトウェア工学の世界はあまりに広大で、スタックのすべての部分を知ることはずっと前からほぼ不可能になっている。
そのうえソフトウェア工学は学びの旅であり、人はそれぞれ旅路の異なる場所にいる。
逆アセンブラ を開いたりデバッガをアタッチしたりするのは言うまでもなく、そうした技術自体が今ではあまり教えられていないようだ。
普段はほぼ即座に終わるとしても、時間がかかる場合に備えてローディングスピナーを置いておくのは理にかなっている。
あるユーザーが、特定のフォームに入力した文言が保存すると変わってしまうと言ってきたことがあり、それがいちばん奇妙だった。
最初は同じフォームを別の人が同時に編集しているのかと思ったが、ログを見る限りそうではなく、私のPCでは正しい文言が表示されていた。
その後、スクリーンショットの中で一部のメニュー文言もおかしいことに気づき、原因はChromeの「このページを翻訳」オプションが有効になっていたことだと分かった。
アプリ内で正しく言語を切り替える方法を案内したところ、問題は解消した。
いまはアプリや要素に適用できる新しいお作法はこれらしい。動的な変更をサポートしないためかCSSではないようで、見た目も美しくない: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_att...
ときどき巨大なシングルページアプリのメタタグを見ていて、なぜそのタグが必要なのかを調べるうちに新たな恐怖を発見することがある。
日本語のWebサイトを読むときにGoogle Translateに頼ることがよくあるのだが、Reactを使っているWebサイトはすべて壊れる。
ReactとGoogle Translateが、お互いの存在を知らないまま DOMノード を更新しようとするからだ。
あとでこの問題のないWebウィジェットを作り直せるか試そうと思って、Google Translateの実装を真剣に調べたことさえある。
[1] https://bugs.chromium.org/p/chromium/issues/detail?id=872770
あまりにも見覚えのある問題だ。
以前、Chromeの アクセシビリティツール がドロップダウンメニューでこうした問題を起こすのを見たことがあり、ごく小さなHTMLでも再現できるほどだった。
2年前に自分が踏んだ特定のバグはChromium-Edgeにあったが、症状も原因も非常によく似ていた。
Grammarlyはほぼ確実にChromeのアクセシビリティツールの一部に依存しているはずだ。
こうしたツールは、Edge、Brave、ChromeといったChromium系ブラウザごとに少しずつ異なる。
次にこういうことが起きたら、単に別のブラウザを使わせるのを勧める。
とくにFirefoxは、Chromeからブックマークやパスワードなどを取り込む機能がずっと良くなっている。
宇宙がいまこそ乗り換えどきだという サイン を送ってきたのであって、我々にそのサインを拒むことはできない。
ちなみに私はFirefoxのエンジニアだが、この助言とは何の関係もない。
PMの立場では、オンボーディングを簡単にするのに4か月も費やしたのに、今度はユーザーに新しいブラウザをインストールしろと言うのか、という話になる。
ブラウザベースの製品が、世界で最も使われているブラウザでまともに動かないのは良い兆候ではない。
セキュリティ上の理由で Chrome のクラッシュレポートはブロックしておきながら、社員が Grammarly をインストール できるようにしている企業のセキュリティポリシー、本当に気に入ってる