M1 Mac で macOS Big Sur 11.2 に更新したら M1 native な node が壊れたので、ソースを変更して動くようにしたメモです。
追記: node v15.9.0 で修正されました。
現象
homebrew で最新版の node v15.8.0 を入れて React での開発に使ってましたが、macOS を更新したら create-react-app で作ったプロジェクトで yarn start
がクラッシュするようになりました。(create-react-app を使わずに webpack serve
してれば大丈夫なようですが…。)
エラーを見る
Starting the development server...
#
# Fatal error in , line 0
# Check failed: allocator->SetPermissions(reinterpret_cast<void*>(region.begin()), region.size(), PageAllocator::kNoAccess).
#
#
#
#FailureMessage Object: 0x16d2c3268
1: 0x102c29104 node::NodePlatform::GetStackTracePrinter()::$_3::__invoke() [/opt/homebrew/Cellar/node/15.8.0/bin/node]
2: 0x1035b4054 V8_Fatal(char const*, ...) [/opt/homebrew/Cellar/node/15.8.0/bin/node]
3: 0x10319d358 v8::internal::wasm::WasmCodeAllocator::GetNumCodeSpaces() const [/opt/homebrew/Cellar/node/15.8.0/bin/node]
4: 0x10319d1f8 v8::internal::wasm::WasmCodeAllocator::FreeCode(v8::internal::Vector<v8::internal::wasm::WasmCode* const>) [/opt/homebrew/Cellar/node/15.8.0/bin/node]
5: 0x1031a0048 v8::internal::wasm::NativeModule::FreeCode(v8::internal::Vector<v8::internal::wasm::WasmCode* const>) [/opt/homebrew/Cellar/node/15.8.0/bin/node]
6: 0x1031adbcc v8::internal::wasm::WasmEngine::FreeDeadCodeLocked(std::__1::unordered_map<v8::internal::wasm::NativeModule*, std::__1::vector<v8::internal::wasm::WasmCode*, std::__1::allocator<v8::internal::wasm::WasmCode*> >, std::__1::hash<v8::internal::wasm::NativeModule*>, std::__1::equal_to<v8::internal::wasm::NativeModule*>, std::__1::allocator<std::__1::pair<v8::internal::wasm::NativeModule* const, std::__1::vector<v8::internal::wasm::WasmCode*, std::__1::allocator<v8::internal::wasm::WasmCode*> > > > > const&) [/opt/homebrew/Cellar/node/15.8.0/bin/node]
7: 0x1031abbec v8::internal::wasm::WasmEngine::PotentiallyFinishCurrentGC() [/opt/homebrew/Cellar/node/15.8.0/bin/node]
8: 0x1031ace28 v8::internal::wasm::WasmEngine::ReportLiveCodeForGC(v8::internal::Isolate*, v8::internal::Vector<v8::internal::wasm::WasmCode*>) [/opt/homebrew/Cellar/node/15.8.0/bin/node]
9: 0x1031ad118 v8::internal::wasm::WasmEngine::ReportLiveCodeFromStackForGC(v8::internal::Isolate*) [/opt/homebrew/Cellar/node/15.8.0/bin/node]
10: 0x102e10ea4 v8::internal::StackGuard::HandleInterrupts() [/opt/homebrew/Cellar/node/15.8.0/bin/node]
11: 0x1030a0938 v8::internal::Runtime_StackGuard(int, unsigned long*, v8::internal::Isolate*) [/opt/homebrew/Cellar/node/15.8.0/bin/node]
12: 0x10332278c Builtins_CEntry_Return1_DontSaveFPRegs_ArgvOnStack_NoBuiltinExit [/opt/homebrew/Cellar/node/15.8.0/bin/node]
13: 0x1032bb530 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
14: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
15: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
16: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
17: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
18: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
19: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
20: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
21: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
22: 0x1032b2ac4 Builtins_ArgumentsAdaptorTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
23: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
24: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
25: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
26: 0x1032b2ac4 Builtins_ArgumentsAdaptorTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
27: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
28: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
29: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
30: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
31: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
32: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
33: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
34: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
35: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
36: 0x1032b2ac4 Builtins_ArgumentsAdaptorTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
37: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
38: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
39: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
40: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
41: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
42: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
43: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
44: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
45: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
46: 0x1032b2ac4 Builtins_ArgumentsAdaptorTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
47: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
48: 0x1032b2ac4 Builtins_ArgumentsAdaptorTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
49: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
50: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
51: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
52: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
53: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
54: 0x1032b2ac4 Builtins_ArgumentsAdaptorTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
55: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
56: 0x1032b2ac4 Builtins_ArgumentsAdaptorTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
57: 0x1032bb494 Builtins_InterpreterEntryTrampoline [/opt/homebrew/Cellar/node/15.8.0/bin/node]
58: 0x10336ea1c Builtins_PromiseFulfillReactionJob [/opt/homebrew/Cellar/node/15.8.0/bin/node]
59: 0x1032da608 Builtins_RunMicrotasks [/opt/homebrew/Cellar/node/15.8.0/bin/node]
60: 0x1032b8c28 Builtins_JSRunMicrotasksEntry [/opt/homebrew/Cellar/node/15.8.0/bin/node]
61: 0x140008000
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
検索したところ、nodejs/node の issue #37061 が見つかりました。どうやらメモリの実行許可に関する動作変更に V8 の WebAssembly JIT が引っ掛かったようです。
根本的な修正ではないものの、node/deps/v8/src/wasm/wasm-code-manager.cc
の以下の 2 行 をコメントアウトすれば問題は回避できるとのことで、早速対応しました。
CHECK(allocator->SetPermissions(reinterpret_cast<void*>(region.begin()),
region.size(), PageAllocator::kNoAccess));
対応
手動でソースを取ってくるのが面倒なので、nvm を使いました。まずは普通に node v15.8.0 をインストール。ビルドの時間は測ってなかったけど、たぶん 10 分くらいかかりました。
% git clone https://github.com/nvm-sh/nvm.git ~/.nvm
% source ~/.nvm/nvm.sh
% nvm install node
この状態で yarn start
して、やはりクラッシュすることを確認。nvm では、ビルドしたソースがそのまま ~/.nvm/.cache/src
の下に転がってるので、それを変更してビルド。
% cd ~/.nvm/.cache/src/node-v15.8.0/files
% vi deps/v8/src/wasm/wasm-code-manager.cc # 問題の箇所をコメントアウト
% make
今度は変更した部分だけのビルドなので、すぐに終了。できたものは out/Releases/node
にあるので、これを ~/.nvm/versions/node/v15.8.0/bin
にコピーしました。
% cd ~/.nvm/versions/node/v15.8.0/bin
% mv node node.bak # 元の node を待避
% cp -p ~/.nvm/.cache/src/node-v15.8.0/files/out/Releases/node .
これで無事に yarn start
できるようになりましたとさ。めでたしめでたし。
(なお、nvm をずっと有効にするには ~/.bashrc
や ~/.zshrc
に source ~/.nvm/nvm.sh
を追加する必要がありますが、自分は一時的な対応のつもりなので、PATH に直接 ~/.nvm/versions/node/v15.8.0/bin
を追加しました。)