Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Cybozu Tech Conference 2016 バグの調べ方

3,682 views

Published on

https://cybozutech2016.qloba.com/

Published in: Technology
  • Be the first to comment

Cybozu Tech Conference 2016 バグの調べ方

  1. 1. バグの調べ方 Cybozu Tech Conrefence 2016 12/13 サイボウズ・ラボ 光成滋生
  2. 2. • 自己紹介 • 自分が開発してるもの • サイボウズ・ラボユース紹介 • 不具合調査 • サイボウズOfficeでの不具合 • Garoonでの不具合 • WalBでの不具合 • まとめ 概要 2 / 29
  3. 3. 自己紹介
  4. 4. • サイボウズの研究開発部門 • 次世代の製品・サービスの基盤となる技術を 中長期視点で研究開発する • 私 • 主にセキュリティ関係に関わる • https://github.com/herumi/ • サブでcybozu.comのバックアップレプリケーションシステム • + たまにやってくる不具合調査 サイボウズ・ラボ 4 / 29
  5. 5. • https://github.com/herumi/mcl • 汎用楕円曲線・ペアリング暗号ライブラリ • https://github.com/herumi/ate-pairing • 世界最速実装の一つ(IEEE Trans. on Computers, 2015) • 何に使うの? • 『クラウドを支えるこれからの暗号技術』 をご覧ください • 例:完全匿名可能な分散型暗号通貨 Zcashのゼロ知識証明プロトコル ペアリング暗号の実装 5 / 29
  6. 6. • https://github.com/herumi/xbyak • 暗号ライブラリなどのために開発 • 来年やその後に出る予定のCPUのAVX-512に対応 • gcc-6, clang-4, NASM, VC2015, Intel SDEなどのツールは AVX512_4FMAPS, AVX512_4VNNIWに未対応(2016/11) • Intelの機械学習ライブラリCaffeやMKL-DNNで利用される C++用JITアセンブラXbyak 実装したけど正しく動いてるかツールが無いので分からん 未公開のIntelソフトウェアXEDで確認したよ 6 / 29
  7. 7. • http://labs.cybozu.co.jp/youth/requirements.html • 学生が作りたいものをサポートする • サイボウズ・ラボ社員がメンター • 比較的長期(最大1年) • 開発物はオープンソース • 給料がもらえる • 私がメンター担当したもの(一部) • 正規表現JITエンジン開発 • JavaScriptエンジン開発 • ペアリング暗号ライブラリ開発 • Intel DPDKを用いたネットワークライブラリ開発 サイボウズ・ラボユース 7 / 29
  8. 8. サイボウズOfficeでの不具合調査
  9. 9. • サイボウズOffice:中小企業向けグループウェア • ファイルキャッシュの不具合(2012年の話) • 1000秒おきにファイルキャッシュがクリア 突然サイボウズOfficeが遅くなる Office ext3 mdadm LVM kernel/driver disk ファイルシステム ソフトウェアRAID パーティション管理 メモリにキャッシュ 誰かにクリア されて遅くなる 9 / 29
  10. 10. • 手元の環境で再現させる • 結構つらい • 仕掛ける • 普通ユーザランドでキャッシュを明示的に破棄しない • 犯人はだれだ • ページキャッシュに関係するkernelの関数をwatch • flush_disk, invalidate_disk, invalidate_partition, ... • ftrace • 低負荷で手軽に使えるkernelトレーサ 再現させる&仕掛ける 10 / 29
  11. 11. • invalidate_partitionが呼ばれた • 呼び出したのはmdadm • 犯人はこいつか • gdbでattach ヒット mdadm-900 [001] .... 75491.384221: __invalidate_device <-invalidate_partition => ftrace_call => invalidate_partition => rescan_partitions => __blkdev_get => blkdev_get ... => do_sys_open => sys_open gdb -p 9000 gdb) bt #0 0x00007f85b1ebf103 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:82 #1 0x000000000040de66 in mdstat_wait (seconds=1000) at mdstat.c:317 #2 0x000000000042dea1 in Monitor (devlist=0x0, mailaddr=0x1a7b020 "root", waitしてる時間が1000秒 11 / 29
  12. 12. • mdのモニタツールがinvalid_partitionを呼んでいる • 呼ぶとはとても思えないが... • /dev/mdをオープンするだけでクリアされると判明 • mdのドライバが犯人か? 位置関係(1/3) mdデーモン md driver disk driver disk invalid_partition() キャッシュクリア モニタツール ? fd = open("dev/md/test..", O_RDONLY); kernel user 12 / 29
  13. 13. • md_open()がinvalid_partitionを呼ぶとは思えない... • 調べたがmd_openは悪くはなかった • スタックトレースの途中にあったblkdev_get()を見てみる 位置関係(2/3) mdデーモン md driver disk driver disk invalid_partition() キャッシュクリア モニタツールopen() md_open() ? kernel user 13 / 29
  14. 14. • bd_invalidatedが怪しい blkdev_get __blkdev_get(...) { ... ret = disk->fops->open(bdev, mode); ... if (bdev->bd_invalidated) { if (!ret) rescan_partitions(disk, bdev); else if (ret == -ENOMEDIUM) invalidate_partitions(disk, bdev); md_openが 呼ばれる __invalidate_partitionが呼ばれる 14 / 29
  15. 15. • mdは悪くなかった • kernel/fsのバグ • check_disk_size_change()内でbd_invalidatedをクリアし忘れ • kernel patchを送る 位置関係(3/3) mdデーモン md driver disk driver disk bd_invalidatedがtrueなら invalid_partition() モニタツールopen() blk_dev() kernel user md_open() // 引っかけ キャッシュクリア 15 / 29
  16. 16. Garoonでの不具合調査
  17. 17. • Garoon:中堅・大規模組織向けグループウェア • リリース予定の少し前に不具合が発覚(2015年の話) • PHPのheapが壊れて死んだ • 本社チームがさまざまな設定で検証 • OPcacheを無効にすると発生しない • OPcache : PHPのコンパイル結果をキャッシュして高速化 • パフォーマンス劣化は許容範囲外 • opcache.max_accelerated_filesを増やすと発生しない • Garoonのファイルは約7000個 • ファイルキャッシュを越えると不具合か? 突然Garoonが白くなる [.10:59:22] WARNING: [pool www] child 19055 said into stderr: "zend_mm_heap corrupted" [.10:59:22] WARNING: [pool www] child 19055 exited with code 1 after 946.944662 seconds from start 17 / 29
  18. 18. • Address sanitizerで調査 • エラーで落ちるがそのメモリがどう壊れてるのか、 どこで確保されたのかはわからない • 自前ツールで調査 • 全てのmalloc/freeを記録して整合性をチェック • 共有ライブラリを通してかなり複雑なやりとりをしている • ひとまず解決 • このバージョンのPHPではopcache.fast_shutdown=0だと エラーになるパスを通らないことを確認 • パフォーマンス劣化も許容範囲内 • 同時に軽微なメモリ破壊の修正patch メモリチェックツール 18 / 29
  19. 19. WalBでの不具合調査その1
  20. 20. • WalB • cybozu.comの次期バックアップレプリケーションシステム • ブロックデバイスの全IOを記録する • デーモン・制御ツールはC++/Python • ラボ:星野(メイン) + 私(サブ) • 現在、星野とSRE(インフラ)チームで本運用に向け最終開発 WalBでおかしな実行バイナリ WalB storage アプリケーション Diff backup storage replicated storage 20 / 29
  21. 21. • gdbでデバッグしようとしたらgdbが落ちる • 起動も何もしていない • gdbを使わなければプログラム自体は普通に動く • 1行だけデータをコメントアウトしたらgdbでも動いた ある日のデバッグ gdb --args binsrc/archive-server -vg vg1 -p 10201 -b /home/shigeo/Program/walb- tools/stest/tmp/a1 -l /home/shigeo/Program/walb-tools/stest/tmp/a1.log -id a1 - debug GNU gdb (Ubuntu 7.7-0ubuntu3.1) 7.7 ...(snip) Type "apropos word" to search for commands related to "word"... Reading symbols from binsrc/archive-server...Segmentation fault (core dumped) const protocol::Str2ServerHandler archiveHandlerMap = { ... // { dirtyFullSyncPN, s2aDirtyFullSyncServer }, /* 動く・動かないの分岐点 */ }; 21 / 29
  22. 22. • 3万行のコードからひたすらコードを削る • 少し変更するだけで動いたり、動かなかったりで難しい • 最終的に30行ほどで落ちるコード • 結局gdbのシンボルパーサにバグ • template+継承+ラムダ式のコンボによる複雑なシンボル • 当時のcurrent版で修正済みだった おもしろい 22 / 29
  23. 23. WalBでの不具合調査その2
  24. 24. • 試験運用時書き込みデータ(logpack)に不正を検出 • しばらくretryしてシステムは継続 • 一度しか発生せず致命的ではなかったため様子見 • しかし20日後再現 • 対応作業 • コードレビュー • チェックコード • 3週間に一度しか起こらないのでよくわからない WalBで不正なlogを検出 24 / 29
  25. 25. • エラーの再現頻度を上げるチェッカーツールの作成 • 最短で10分に一度エラーが発生! • 条件によって数時間走らせても出ないことも • WalB driverのflushまわりの制御バグを発見 • ツールを1日走らせてもエラーが出なくなった • 問題解決か? • 残念 • ツールを使っても3日に一度エラーが発生 原因究明作業(主に星野担当) 25 / 29
  26. 26. • diskの読み書きは非同期 • データは分割・統合されうる • 実際にはflush処理もある 原因追求が難しい理由 write() user空間 WalB driver/kernel空間 logの書き込みsubmit disk 書き込み complete完了 dataのコピー・統合・分割 dataの書き込みsubmit 書き込み complete 26 / 29
  27. 27. • いろいろ調べても悪そうには見えない • 環境によって出るのと出ないのと • 同じマシンでも出やすかったりそうでなかったり • 何が違うのかなかなか思い当たらない • つらい期間 • WalBのせいじゃないのではないかという仮定の元に 複数書き込みを模倣するユーザランドツールを作成 • 同じエラーが発生 • WalB driverのせいではなかった! • では犯人はdisk driver or kernel? WalB driverのせいなのか? 27 / 29
  28. 28. • disk IOを詳細に取得できるツール • completedでdiskの書き込みは完了しているはずなのに 3296001番目のセクタの中身はは0のままだった • RAIDカードのドライバかファームウェアの不具合 blktrace 252,7 1 12079 228.808092957 4494 Q W 3296001 + 1 [kworker/u66:21] 8,2 1 162836 228.808094689 4494 A W 622367489 + 1 <- (252,7) 3296001 8,0 1 162837 228.808095153 4494 A W 622867201 + 1 <- (8,2) 622367489 8,0 1 162838 228.808095648 4494 Q W 622867201 + 1 [kworker/u66:21] 8,0 1 162839 228.808099628 4494 G W 622867201 + 1 [kworker/u66:21] 252,7 1 12080 228.808101183 4494 Q W 3296002 + 256 [kworker/u66:21] 8,2 1 162840 228.808101724 4494 A W 622367490 + 256 <- (252,7) 3296002 ... (snip) ... 8,0 1 162854 228.808198793 4494 Q W 622867459 + 256 [kworker/u66:21] 8,0 1 162855 228.808199268 4494 G W 622867459 + 256 [kworker/u66:21] 8,0 7 187897 228.808255052 4367 C W 622867202 + 256 [0] 252,7 7 19389 228.808256993 4367 C W 3296002 + 256 [0] 8,0 7 187898 228.808260877 4367 C W 622867201 + 1 [0] 252,7 7 19390 228.808261198 4367 C W 3296001 + 1 [0] heder submitted logpack submitted logpack completed header completed 28 / 29
  29. 29. • まずは自分たちのコードを疑う • ほとんどは自分のミス • 論理的に、ときにはひらめきで追いかける • ありそうにないものが犯人のときもある • つらいときでも耐える • 気分転換でもして バグの調べ方のまとめ 29 / 29

×