Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
ファームウェアの Panic を 自動で収集・解析・分類・集計して 市場品質の改善サイクルを回す
Hideaki Tai
September 29, 2022
Technology
0
300
ファームウェアの Panic を 自動で収集・解析・分類・集計して 市場品質の改善サイクルを回す
Bitkey x Nature / IoTぶっちゃけNight での発表資料です。
https://nature.connpass.com/event/257336/
Hideaki Tai
September 29, 2022
Tweet
Share
More Decks by Hideaki Tai
See All by Hideaki Tai
ofserial-option
hideakitai
0
53
Other Decks in Technology
See All in Technology
OCI技術資料 : ロード・バランサー 詳細 / Load Balancer 200
ocise
2
7.2k
ML PM, DS PMってどんな仕事をしているの?
line_developers
PRO
1
240
DNS権威サーバのクラウドサービス向けに行われた攻撃および対策 / DNS Pseudo-Random Subdomain Attack and mitigations
kazeburo
5
1.3k
Deep Neural Networkの共同学習
hf149
0
300
03_ユーザビリティテスト
kouzoukaikaku
0
510
Deep dive in Reserved Instance ~脳死推奨量購入からの脱却~
kzkmaeda
0
540
CES_2023_FleetWise_demo.pdf
sparkgene
0
120
Hatena Engineer Seminar #23 「チームとプロダクトを育てる Mackerel 開発合宿」
arthur1
0
530
Oktaの管理者権限を適切に移譲してみた
shimosyan
2
270
私見「UNIXの考え方」/20230124-kameda-unix-phylosophy
opelab
0
160
01_ユーザーリサーチ実施の進め方
kouzoukaikaku
0
540
OCI DevOps 概要 / OCI DevOps overview
oracle4engineer
PRO
0
500
Featured
See All Featured
A better future with KSS
kneath
230
16k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
500
130k
How GitHub (no longer) Works
holman
298
140k
Agile that works and the tools we love
rasmusluckow
320
20k
Bootstrapping a Software Product
garrettdimon
299
110k
Six Lessons from altMBA
skipperchong
15
2.3k
How STYLIGHT went responsive
nonsquared
89
4.2k
How to train your dragon (web standard)
notwaldorf
66
4.3k
Producing Creativity
orderedlist
PRO
335
38k
Web Components: a chance to create the future
zenorocha
304
40k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
10
1.3k
Fashionably flexible responsive web design (full day workshop)
malarkey
396
63k
Transcript
2022/09/28 ファームウェアの Panic を 自動で収集・解析・分類・集計して 市場品質の改善サイクルを回す
自己紹介 - 田井 秀昭 - ハードウェア + メディアテクノロジーを楽しんでいる人 - Arduino
/ 回路 -> 光・音・ロボティクス・ウェアラブル - Nature SWE (FW) <- Rhizomatiks HW <- 電機メーカー HW - HP / GitHub / Twitter
Nature Remo では普段から 様々なエラーログを収集しています 🗒
市場には未知のバグが潜んでいるはず…! ☠
(天の声) Backtrace を収集したいですよね? 💡
ESP-IDF は Panic したら Backtrace を出してくれる Guru Meditation Error: Core
0 panic'ed (Cache disabled but cached memory region accessed). Exception was unhandled. Core 0 register dump: PC : 0x400e14ed PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030 A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000001 A5 : 0x3ffb50dc A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x3ffb5000 A10 : 0x00000000 A11 : 0x3ffb2bac A12 : 0x40082d1c A13 : 0x06ff1ff8 A14 : 0x3ffb7078 A15 : 0x00000000 SAR : 0x00000014 EXCCAUSE: 0x0000001d EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0xffffffff Backtrace: 0x400e14ed:0x3ffb5030 0x400d0802:0x3ffb5050 参考: Fatal Errors # ESP-IDF を Activate した状態で下記のようなツールで Backtrace を手動でデコードできる xtensa-esp32-elf-addr2line -pfiaC -e firmware.elf {Backtrace の文字列}
IDF Monitor で見ていれば自動でデコードしてくれる Core 0 register dump: PC : 0x400e14ed
PS : 0x00060030 A0 : 0x800d0805 A1 : 0x3ffb5030 0x400e14ed: app_main at /Users/user/esp/example/main/main.cpp:36 A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000001 A5 : 0x3ffb50dc A6 : 0x00000000 A7 : 0x00000001 A8 : 0x00000000 A9 : 0x3ffb5000 A10 : 0x00000000 A11 : 0x3ffb2bac A12 : 0x40082d1c A13 : 0x06ff1ff8 0x40082d1c: _calloc_r at /Users/user/esp/esp-idf/components/newlib/syscalls.c:51 A14 : 0x3ffb7078 A15 : 0x00000000 SAR : 0x00000014 EXCCAUSE: 0x0000001d EXCVADDR: 0x00000000 LBEG : 0x4000c46c LEND : 0x4000c477 LCOUNT : 0xffffffff Backtrace: 0x400e14ed:0x3ffb5030 0x400d0802:0x3ffb5050 0x400e14ed: app_main at /Users/user/esp/example/main/main.cpp:36 0x400d0802: main_task at /Users/user/esp/esp-idf/components/esp32/cpu_start.c:470
ESP-IDF の Backtrace 出力をハックして 収集できたら最高では? 🤔
ただし条件がある! ⚠
Firmware OTA Update でのトラブルを起こさない! - 独自に ESP-IDF を Fork して変更したくない
- 稼働中の数十万台の Remo の Flash の Partition は変えたくない - なるべく DRAM の容量を節約したい - Panic 中に Panic だけはしないように細心の注意を!!
どうしたら良いか? 🤔
Backtrace を安全に収集するために解決すべきこと - 独自に ESP-IDF を Fork して変更したくない - 稼働中の数十万台の
Remo の Flash の Partition は変えたくない - なるべく DRAM の容量を節約したい - Panic 中に Panic だけはしないように細心の注意を!!
ESP-IDF で Backtrace を出力する流れはこんな感じらしい // ESP-IDF で実装されている Backtrace を表示する Public
な関数 void panic_print_backtrace(const void *f, int core) { /* … */ } 参考: esp-idf/components/esp_system/port/arch/xtensa/panic_arch.c
(天の声) リンカの wrap 機能はいかが? 💡
リンカの wrap 機能で既存の Public な関数を wrap する LDFLAGS=-Wl,--wrap=panic_print_backtrace // 元の
panic_print_backtrace() は __real prefix を付ければ呼び出せる extern void __real_panic_print_backtrace(const void* f, int core); // 元の panic_print_backtrace() の呼び出しは __wrap prefix のものに置き換えられる void __wrap_panic_print_backtrace(const void* f, int core) { // ここで Backtrace を保存する // 必要であれば、元の実装を呼び出す __real_panic_print_backtrace(f, core); } // ESP-IDF で実装されている Backtrace を表示する Public な関数 void panic_print_backtrace(const void *f, int core) { /* … */ } 下記のように wrap 関数を定義し、LDFLAGS をつけてコンパイルすれば、 ESP-IDF を Fork したりせずとも Public な関数をハックできる!
- 独自に ESP-IDF を Fork して変更したくない - 稼働中の数十万台の Remo の
Flash の Partition は変えたくない - なるべく DRAM の容量を節約したい - Panic 中に Panic だけはしないように細心の注意を!! Backtrace を安全に収集するために解決すべきこと
どうやって再起動後まで Backtrace を保存するか? - 再起動後まで Backtrace のデータを保持するには、いくつかやり方がある - ESP-IDF の
Core Dump 機能を使う (🆖 Flash に専用の Partition を作る必要がある) - リセットしても消えない DRAM領域を使う (🆖 DRAM 容量を節約したい) - リセットしても消えない RTC Slow Memory を使う (🆗 Flash を使用せずに 8KB 使える!) - 👉 リセットしても消えない RTC Slow Memory に Backtrace を保存する - Partition を変更する必要がない - DRAM 容量を節約できる // RTC Slow Memory 上に配置するデータ static RTC_NOINIT_ATTR int s_cached_panicked_core; static RTC_NOINIT_ATTR uint32_t s_pcs[BACKTRACE_CACHE_MAX_DEPTH]; static RTC_NOINIT_ATTR uint32_t s_sps[BACKTRACE_CACHE_MAX_DEPTH]; static RTC_NOINIT_ATTR size_t s_cached_backtrace_depth; static RTC_NOINIT_ATTR backtrace_status_t s_cached_backtrace_status;
- 独自に ESP-IDF を Fork して変更したくない - 稼働中の数十万台の Remo の
Flash の Partition は変えたくない - なるべく DRAM の容量を節約したい - Panic 中に Panic だけはしないように細心の注意を!! Backtrace を安全に収集するために解決すべきこと
実機テストで Panic 中に Panic したりしないか入念に確認 // Backtrace が想定どおり取れるかテスト (restart, abort,
assert, wdt, stack/buffer overflow) // 最後に余計な Panic なく想定どおりの回数だけ Panic していることを確認する typedef enum { TEST_STATE_INITIALIZE, TEST_STATE_RESTART, …, TEST_STATE_ABORT_CORE0, TEST_STATE_ABORT_CORE1, …, TEST_STATE_ASSERT_CORE0, TEST_STATE_ASSERT_CORE1, …, TEST_STATE_WATCHDOG_CORE0, TEST_STATE_WATCHDOG_CORE1, …, TEST_STATE_STACK_OVERFLOW_CORE0, TEST_STATE_STACK_OVERFLOW_CORE1, …, TEST_STATE_BUFFER_OVERFLOW_CORE0, TEST_STATE_BUFFER_OVERFLOW_CORE1, …, TEST_STATE_FINALIZE, } test_state_t; static RTC_NOINIT_ATTR test_state_t s_test_state; // RTC Memory に保存してテスト状況を追跡 static RTC_NOINIT_ATTR size_t s_panic_count; // 想定外に Panic していないか監視 const size_t MAX_PANIC_COUNT = 10; // このテストで Panic する回数
[まとめ] Backtrace を保存してサーバへ送信する 1. リンカの wrap 機能を使って Panic 時の Backtrace
表示関数を wrap ◦ ESP-IDF を Fork したりせずにハックできる! 2. RTC Slow Memory (.noinit 領域) を使って Backtrace 情報を保存 ◦ Partition を変更しない + DRAM 容量を節約して保存できる! 3. RTC Slow Memory に Backtrace 情報が保存されていたらサーバへ送信 ※ 実機テストで Panic 中に Panic するなどの致命的な不具合がないことを確認
[まとめ] Backtrace を保存してサーバへ送信する
ファームウェア側は完成! 🙌
サーバに送信した後は… - Backtrace を自動でデコードしてくれたらもっと良いのでは? - 自動でエラー解析をして原因箇所と経路を特定してもらえる - すぐに改善の検討を始められる - さらに自動でエラーを分類・集計・報告してくれたら最高では?
- 市場の影響度 (改善の優先度) も見えるようになる
Remo の Backtrace を自動で収集してくれる君の概要
不慣れな開発をする私に試練が襲いかかる… しかし
神 (1) が現れ 20 分で Go のバグを解決してくれる…
神 (2) が現れ sentry を紹介してくれる…
最高 🙌
sentry で Backtrace を自動で収集・分類・集計 (参考)
本日のまとめ - リンカの wrap 機能を使って IDF を変更せずに挙動をハックした - ESP の
RTC Slow Memory を使って再起動後まで Backtrace を保存した - 市場の製品に影響を与えないよう入念に実機テストを行った - Nature の仲間の力を借りれば良い感じのシステムが構築できる!
Nature では積極採用中です - Nature では一緒に開発をしてくれる仲間を募集しています - カジュアル面談も大歓迎です - Culture Deck
: ミッション・サービス・組織・文化・福利厚生をご覧下さい
ご清聴ありがとうございました 🙌