Skip to content

--experimental-enable-pointer-compression causes build failure #51339

Description

@codebytere

Version

v22.0.0-pre

Platform

Darwin Shelleys-MacBook-Pro-2.local 23.2.0 Darwin Kernel Version 23.2.0: Wed Nov 15 21:53:18 PST 2023; root:xnu-10002.61.3~2/RELEASE_ARM64_T6000 arm64

Subsystem

No response

What steps will reproduce the bug?

  1. ./configure --ninja --experimental-enable-pointer-compression
  2. ninja -C out/Release

How often does it reproduce? Is there a required condition?

Consistently with the above steps.

What is the expected behavior? Why is that the expected behavior?

A successful build with pointer compression enabled.

What do you see instead?

The following build failure:

Build Failure

node on git:main ❯ ninja -C out/Release                                             2:39PM
Running "ninja -C out/Release"
ninja: Entering directory `out/Release'
[1/1712] CC obj/deps/v8/third_party/zlib/v8_zlib.cpu_features.o
../../deps/v8/third_party/zlib/cpu_features.c:99:13: warning: unused function '_cpu_check_features' [-Wunused-function]
static void _cpu_check_features(void)
            ^
1 warning generated.
[16/1712] CC obj/deps/v8/third_party/zlib/v8_zlib.deflate.o
../../deps/v8/third_party/zlib/deflate.c:2003:31: warning: comparison of integers of different signs: 'IPos' (aka 'unsigned int') and 'int' [-Wsign-compare]
            if (s->prev_match == -1) {
                ~~~~~~~~~~~~~ ^  ~~
1 warning generated.
[99/1712] ACTION icudata: icudata_cc7672230cb6f4a4cb1b079ff599d36f
generating assembly code for /Users/codebytere/Developer/node/out/Release/gen/icudt74.dat
[1097/1709] LIBTOOL-STATIC libv8_base_without_compiler.a, POSTBUILDS
/Users/codebytere/.electron_build_tools/third_party/Xcode/Xcode-15.0.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning renaming duplicate member name 'v8_base_without_compiler.allocation.o' from 'obj/deps/v8/src/heap/cppgc/v8_base_without_compiler.allocation.o(v8_base_without_compiler.allocation.o)' and 'obj/deps/v8/src/utils/v8_base_without_compiler.allocation.o(v8_base_without_compiler.allocation.o)'
/Users/codebytere/.electron_build_tools/third_party/Xcode/Xcode-15.0.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning renaming duplicate member name 'v8_base_without_compiler.factory.o' from 'obj/tools/v8_gypfiles/gen/torque-generated/v8_base_without_compiler.factory.o(v8_base_without_compiler.factory.o)' and 'obj/deps/v8/src/heap/v8_base_without_compiler.factory.o(v8_base_without_compiler.factory.o)'
/Users/codebytere/.electron_build_tools/third_party/Xcode/Xcode-15.0.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning renaming duplicate member name 'v8_base_without_compiler.free-list.o' from 'obj/deps/v8/src/heap/cppgc/v8_base_without_compiler.free-list.o(v8_base_without_compiler.free-list.o)' and 'obj/deps/v8/src/heap/v8_base_without_compiler.free-list.o(v8_base_without_compiler.free-list.o)'
/Users/codebytere/.electron_build_tools/third_party/Xcode/Xcode-15.0.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning renaming duplicate member name 'v8_base_without_compiler.heap.o' from 'obj/deps/v8/src/heap/cppgc/v8_base_without_compiler.heap.o(v8_base_without_compiler.heap.o)' and 'obj/deps/v8/src/heap/v8_base_without_compiler.heap.o(v8_base_without_compiler.heap.o)'
/Users/codebytere/.electron_build_tools/third_party/Xcode/Xcode-15.0.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning renaming duplicate member name 'v8_base_without_compiler.objects-printer.o' from 'obj/deps/v8/src/diagnostics/v8_base_without_compiler.objects-printer.o(v8_base_without_compiler.objects-printer.o)' and 'obj/tools/v8_gypfiles/gen/torque-generated/v8_base_without_compiler.objects-printer.o(v8_base_without_compiler.objects-printer.o)'
/Users/codebytere/.electron_build_tools/third_party/Xcode/Xcode-15.0.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning renaming duplicate member name 'v8_base_without_compiler.sweeper.o' from 'obj/deps/v8/src/heap/v8_base_without_compiler.sweeper.o(v8_base_without_compiler.sweeper.o)' and 'obj/deps/v8/src/heap/cppgc/v8_base_without_compiler.sweeper.o(v8_base_without_compiler.sweeper.o)'
/Users/codebytere/.electron_build_tools/third_party/Xcode/Xcode-15.0.0.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: warning renaming duplicate member name 'v8_base_without_compiler.testing.o' from 'obj/deps/v8/src/sandbox/v8_base_without_compiler.testing.o(v8_base_without_compiler.testing.o)' and 'obj/deps/v8/src/heap/cppgc/v8_base_without_compiler.testing.o(v8_base_without_compiler.testing.o)'
[1646/1709] ACTION generating: "obj/tools/v8_g.../tools/v8_gypfiles/v8_snapshot.gen/embedded.S"
FAILED: obj/tools/v8_gypfiles/v8_snapshot.gen/snapshot.cc obj/tools/v8_gypfiles/v8_snapshot.gen/embedded.S
cd ../../tools/v8_gypfiles; export BUILT_FRAMEWORKS_DIR=/Users/codebytere/Developer/node/out/Release; export BUILT_PRODUCTS_DIR=/Users/codebytere/Developer/node/out/Release; export CONFIGURATION=Release; export EXECUTABLE_NAME=libv8_snapshot.a; export EXECUTABLE_PATH=libv8_snapshot.a; export FULL_PRODUCT_NAME=libv8_snapshot.a; export MACH_O_TYPE=staticlib; export PRODUCT_NAME=v8_snapshot; export PRODUCT_TYPE=com.apple.product-type.library.static; export SDKROOT=/Users/codebytere/.electron_build_tools/third_party/Xcode/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk; export SRCROOT=/Users/codebytere/Developer/node/out/Release/../../tools/v8_gypfiles; export SOURCE_ROOT="${SRCROOT}"; export TARGET_BUILD_DIR=/Users/codebytere/Developer/node/out/Release; export TEMP_DIR="${TMPDIR}"; export XCODE_VERSION_ACTUAL=1500;/Users/codebytere/Developer/node/out/Release/mksnapshot --turbo_instruction_scheduling "--target_os=mac" "--target_arch=arm64" --startup_src /Users/codebytere/Developer/node/out/Release/obj/tools/v8_gypfiles/v8_snapshot.gen/snapshot.cc --embedded_variant Default --embedded_src /Users/codebytere/Developer/node/out/Release/obj/tools/v8_gypfiles/v8_snapshot.gen/embedded.S --no-native-code-counters
/bin/sh: line 1: 94091 Bus error: 10           /Users/codebytere/Developer/node/out/Release/mksnapshot --turbo_instruction_scheduling "--target_os=mac" "--target_arch=arm64" --startup_src /Users/codebytere/Developer/node/out/Release/obj/tools/v8_gypfiles/v8_snapshot.gen/snapshot.cc --embedded_variant Default --embedded_src /Users/codebytere/Developer/node/out/Release/obj/tools/v8_gypfiles/v8_snapshot.gen/embedded.S --no-native-code-counters
[1657/1709] CXX obj/src/quic/libnode.session.o
ninja: build stopped: subcommand failed.
ERROR Failed to run command:
 Exit Code: "1"

Additional information

It looks like it's failing on snapshot generation - @joyeecheung maybe you have some ideas?

Activity

  1. changed the title [-]--experimental-enable-pointer-compression causes build failure[/-] [+]`--experimental-enable-pointer-compression` causes build failure[/+] on Jan 2, 2024
  2. targos commented on Jan 2, 2024

    @targos
    Member

    May be specific to macOS or arm64? It doesn't seem to reproduce in CI: https://ci.nodejs.org/job/node-test-commit-linux-pointer-compression/294/

  3. codebytere commented on Jan 2, 2024

    @codebytere
    MemberAuthor

    huh, interesting 🤔 i'm digging into it because electron is seeing the following issue when running es-module/test-vm-compile-function-lineoffset.js, but only with compression enabled:

    Details

    #
    # Fatal error in ../../v8/src/objects/smi.h, line 37
    # Debug check failed: Smi::IsValid(value).
    #
    #
    #
    #FailureMessage Object: 0x16f730b38
     1: 0x12293f5ec node::NodePlatform::GetStackTracePrinter()::$_0::__invoke() [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
     2: 0x11f36c42c V8_Fatal(char const*, int, char const*, ...) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
     3: 0x11f36c068 std::__Cr::enable_if<!std::is_function<std::__Cr::remove_pointer<unsigned char>::type>::value && !std::is_enum<unsigned char>::value && has_output_operator<unsigned char, v8::base::CheckMessageStream>::value, std::__Cr::basic_string<char, std::__Cr::char_traits<char>, std::__Cr::allocator<char>>>::type v8::base::PrintCheckOperand<unsigned char>(unsigned char) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
     4: 0x11a27e0b4 v8::internal::(anonymous namespace)::SetScriptFieldsFromDetails(v8::internal::Isolate*, v8::internal::Tagged<v8::internal::Script>, v8::internal::ScriptDetails, v8::internal::CombinationAssertScope<v8::internal::PerThreadAssertScopeDebugOnly<(v8::internal::PerThreadAssertType)0, false>, v8::internal::PerThreadAssertScopeDebugOnly<(v8::internal::PerThreadAssertType)1, false>>*) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
     5: 0x11a287b64 v8::internal::(anonymous namespace)::NewScript(v8::internal::Isolate*, v8::internal::ParseInfo*, v8::internal::Handle<v8::internal::String>, v8::internal::ScriptDetails, v8::internal::NativesFlag, v8::internal::MaybeHandle<v8::internal::FixedArray>) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
     6: 0x11a28768c v8::internal::Compiler::GetWrappedFunction(v8::internal::Handle<v8::internal::String>, v8::internal::Handle<v8::internal::FixedArray>, v8::internal::Handle<v8::internal::Context>, v8::internal::ScriptDetails const&, v8::internal::AlignedCachedData*, v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
     7: 0x11a07bed8 v8::ScriptCompiler::CompileFunctionInternal(v8::Local<v8::Context>, v8::ScriptCompiler::Source*, unsigned long, v8::Local<v8::String>*, unsigned long, v8::Local<v8::Object>*, v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason, v8::Local<v8::ScriptOrModule>*) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
     8: 0x11a07bab0 v8::ScriptCompiler::CompileFunction(v8::Local<v8::Context>, v8::ScriptCompiler::Source*, unsigned long, v8::Local<v8::String>*, unsigned long, v8::Local<v8::Object>*, v8::ScriptCompiler::CompileOptions, v8::ScriptCompiler::NoCacheReason) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
     9: 0x1228c53e0 node::contextify::ContextifyContext::CompileFunctionAndCacheResult(node::Environment*, v8::Local<v8::Context>, v8::ScriptCompiler::Source*, std::__Cr::vector<v8::Local<v8::String>, std::__Cr::allocator<v8::Local<v8::String>>>, std::__Cr::vector<v8::Local<v8::Object>, std::__Cr::allocator<v8::Local<v8::Object>>>, v8::ScriptCompiler::CompileOptions, bool, v8::Local<v8::Symbol>, node::errors::TryCatchScope const&) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    10: 0x1228c2658 node::contextify::ContextifyContext::CompileFunction(v8::FunctionCallbackInfo<v8::Value> const&) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    11: 0x157dd3ce0
    12: 0x157dd14bc
    13: 0x157dd14bc
    14: 0x157dd14bc
    15: 0x157dd14bc
    16: 0x157dd14bc
    17: 0x157dd14bc
    18: 0x157dd14bc
    19: 0x157dd14bc
    20: 0x157dd14bc
    21: 0x157dd14bc
    22: 0x157dce688
    23: 0x157dce378
    24: 0x11a388a24 v8::internal::(anonymous namespace)::Invoke(v8::internal::Isolate*, v8::internal::(anonymous namespace)::InvokeParams const&) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    25: 0x11a387d20 v8::internal::Execution::Call(v8::internal::Isolate*, v8::internal::Handle<v8::internal::Object>, v8::internal::Handle<v8::internal::Object>, int, v8::internal::Handle<v8::internal::Object>*) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    26: 0x11a09d14c v8::Function::Call(v8::Local<v8::Context>, v8::Local<v8::Value>, int, v8::Local<v8::Value>*) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    27: 0x1228b4b7c node::builtins::BuiltinLoader::CompileAndCall(v8::Local<v8::Context>, char const*, node::Realm*) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    28: 0x12294e1ac node::Realm::ExecuteBootstrapper(char const*) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    29: 0x12286f6a4 node::StartExecution(node::Environment*, char const*) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    30: 0x12286f5e4 node::StartExecution(node::Environment*, std::__Cr::function<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const&)>) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    31: 0x122822e70 node::LoadEnvironment(node::Environment*, std::__Cr::function<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const&)>) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    32: 0x1187d7274 electron::NodeMain(int, char**) [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    33: 0x1187d2ddc ElectronInitializeICUandStartNode [/Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/Frameworks/Electron Framework.framework/Versions/A/Electron Framework]
    34: 0x18263d0e0 start [/usr/lib/dyld]
    ERROR Error: Command failed: /Users/codebytere/Developer/electron-gn/src/out/Testing/Electron.app/Contents/MacOS/Electron ../third_party/electron_node/test/es-module/test-vm-compile-function-lineoffset.js
        at checkExecSyncError (node:child_process:841:11)
        at Object.execFileSync (node:child_process:876:15)
        at Command.<anonymous> (/Users/codebytere/.electron_build_tools/src/e:117:20)
        at Command.listener [as _actionHandler] (/Users/codebytere/.electron_build_tools/node_modules/commander/lib/command.js:480:17)
        at /Users/codebytere/.electron_build_tools/node_modules/commander/lib/command.js:1234:65
        at Command._chainOrCall (/Users/codebytere/.electron_build_tools/node_modules/commander/lib/command.js:1151:12)
        at Command._parseCommand (/Users/codebytere/.electron_build_tools/node_modules/commander/lib/command.js:1234:27)
        at Command._dispatchSubcommand (/Users/codebytere/.electron_build_tools/node_modules/commander/lib/command.js:1057:25)
        at Command._parseCommand (/Users/codebytere/.electron_build_tools/node_modules/commander/lib/command.js:1200:19)
    

    And i'm so far unable to repro in Node.js proper due to being blocked on this.

    Looks like it can also be seen with the above configuration simply by running:

    node on git:main ❯ /Users/codebytere/Developer/node/out/Release/mksnapshot --turbo_instruction_scheduling "--target_os=mac" "--target_arch=arm64" --startup_src /Users/codebytere/Developer/node/out/Release/obj/tools/v8_gypfiles/v8_snapshot.gen/snapshot.cc --embedded_variant Default --embedded_src /Users/codebytere/Developer/node/out/Release/obj/tools/v8_gypfiles/v8_snapshot.gen/embedded.S --no-native-code-counters
    [1]    6473 bus error  /Users/codebytere/Developer/node/out/Release/mksnapshot  "--target_os=mac"
    
  4. kvakil commented on Jan 2, 2024

    @kvakil
    Contributor

    I can also repro on arm64 macOS (but not on Linux):

    Details
    $ ./configure --ninja --experimental-enable-pointer-compression --v8-with-dchecks --v8-non-optimized-debug
    $ ninja -C out/Release
    ...
    /bin/sh: line 1: 80220 Bus error: 10  ...
    (lldb) bt
    * thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x9a800008010)
      * frame #0: 0x00000001004c0710 mksnapshot`v8::internal::InstructionStream::Initialize(v8::internal::Tagged<v8::internal::HeapObject>, v8::internal::Tagged<v8::internal::Map>, unsigned int, v8::internal::Tagged<v8::internal::ByteArray>) [inlined] void std::__1::__cxx_atomic_store[abi:v160006]<int>(__a=0x000009a800008010, __val=135269005, __order=memory_order_relaxed) at atomic:945:5 [opt]
        frame #1: 0x00000001004c0710 mksnapshot`v8::internal::InstructionStream::Initialize(v8::internal::Tagged<v8::internal::HeapObject>, v8::internal::Tagged<v8::internal::Map>, unsigned int, v8::internal::Tagged<v8::internal::ByteArray>) [inlined] std::__1::__atomic_base<int, false>::store[abi:v160006](this=0x000009a800008010, __d=135269005, __m=memory_order_relaxed) volatile at atomic:1538:10 [opt]
        frame #2: 0x00000001004c0710 mksnapshot`v8::internal::InstructionStream::Initialize(v8::internal::Tagged<v8::internal::HeapObject>, v8::internal::Tagged<v8::internal::Map>, unsigned int, v8::internal::Tagged<v8::internal::ByteArray>) [inlined] void std::__1::atomic_store_explicit[abi:v160006]<int>(__o=0x000009a800008010, __d=135269005, __m=memory_order_relaxed) at atomic:1887:10 [opt]
        frame #3: 0x00000001004c0710 mksnapshot`v8::internal::InstructionStream::Initialize(v8::internal::Tagged<v8::internal::HeapObject>, v8::internal::Tagged<v8::internal::Map>, unsigned int, v8::internal::Tagged<v8::internal::ByteArray>) [inlined] v8::base::Relaxed_Store(ptr=0x000009a800008010, value=135269005) at atomicops.h:200:3 [opt]
        frame #4: 0x00000001004c0710 mksnapshot`v8::internal::InstructionStream::Initialize(v8::internal::Tagged<v8::internal::HeapObject>, v8::internal::Tagged<v8::internal::Map>, unsigned int, v8::internal::Tagged<v8::internal::ByteArray>) [inlined] void v8::base::AsAtomicImpl<int>::Relaxed_Store<unsigned int>(addr=0x000009a800008010, new_value=135269005) at atomic-utils.h:110:5 [opt]
        frame #5: 0x00000001004c0710 mksnapshot`v8::internal::InstructionStream::Initialize(v8::internal::Tagged<v8::internal::HeapObject>, v8::internal::Tagged<v8::internal::Map>, unsigned int, v8::internal::Tagged<v8::internal::ByteArray>) [inlined] v8::internal::TaggedField<v8::internal::Map, 0, v8::internal::V8HeapCompressionScheme>::Relaxed_Store_Map_Word(host=<unavailable>, value=v8::internal::TaggedField<v8::internal::Map, 0, v8::internal::V8HeapCompressionScheme>::PtrType @ x23) at tagged-field-inl.h:139:3 [opt]
        frame #6: 0x00000001004c0710 mksnapshot`v8::internal::InstructionStream::Initialize(v8::internal::Tagged<v8::internal::HeapObject>, v8::internal::Tagged<v8::internal::Map>, unsigned int, v8::internal::Tagged<v8::internal::ByteArray>) [inlined] void v8::internal::ThreadIsolation::WritableJitAllocation::WriteHeaderSlot<v8::internal::Map, 0ul>(this=<unavailable>, value=Map @ x23, (null)=<unavailable>) at code-memory-access-inl.h:75:5 [opt]
        frame #7: 0x00000001004c0704 mksnapshot`v8::internal::InstructionStream::Initialize(self=Tagged<v8::internal::HeapObject> @ x19, map=Tagged<v8::internal::Map> @ x23, body_size=8, reloc_info=Tagged<v8::internal::ByteArray> @ x20) at instruction-stream-inl.h:41:25 [opt]
        frame #8: 0x00000001004bfec8 mksnapshot`v8::internal::Factory::CodeBuilder::BuildInternal(this=0x000000016fdc3830, retry_allocation_or_fail=<unavailable>) at factory.cc:154:45 [opt]
        frame #9: 0x00000001004c1730 mksnapshot`v8::internal::Factory::CodeBuilder::Build(this=<unavailable>) at factory.cc:283:10 [opt]
        frame #10: 0x0000000101c6e03c mksnapshot`v8::internal::SetupIsolateDelegate::PopulateWithPlaceholders(v8::internal::Isolate*) [inlined] v8::internal::(anonymous namespace)::BuildPlaceholder(isolate=0x0000000108008000, builtin=kDeoptimizationEntry_Eager) at setup-builtins-internal.cc:100:28 [opt]
        frame #11: 0x0000000101c6df08 mksnapshot`v8::internal::SetupIsolateDelegate::PopulateWithPlaceholders(isolate=0x0000000108008000) at setup-builtins-internal.cc:225:32 [opt]
        frame #12: 0x0000000101c6eba0 mksnapshot`v8::internal::SetupIsolateDelegate::SetupBuiltinsInternal(isolate=0x0000000108008000) at setup-builtins-internal.cc:302:3 [opt]
        frame #13: 0x000000010118e82c mksnapshot`v8::internal::SetupIsolateDelegate::SetupBuiltins(this=<unavailable>, isolate=0x0000000108008000, compile_builtins=<unavailable>) at setup-isolate-full.cc:29:3 [opt]
        frame #14: 0x00000001003c6cf4 mksnapshot`v8::internal::Isolate::Init(this=0x0000000108008000, startup_snapshot_data=0x0000000000000000, read_only_snapshot_data=<unavailable>, shared_heap_snapshot_data=0x0000000000000000, can_rehash=<unavailable>) at isolate.cc:4635:22 [opt]
        frame #15: 0x00000001003c5944 mksnapshot`v8::internal::Isolate::InitWithoutSnapshot(this=<unavailable>) at isolate.cc:4177:10 [opt]
        frame #16: 0x0000000100d76928 mksnapshot`v8::internal::SnapshotCreatorImpl::SnapshotCreatorImpl(this=0x000000016fde4650, isolate=<unavailable>, api_external_references=0x0000000000000000, existing_blob=<unavailable>, owns_isolate=<unavailable>) at snapshot.cc:885:15 [opt]
        frame #17: 0x0000000100d7589c mksnapshot`v8::internal::CreateSnapshotDataBlobInternal(v8::SnapshotCreator::FunctionCodeHandling, char const*, v8::internal::Isolate*, v8::base::Flags<v8::internal::Snapshot::SerializerFlag, int, int>) [inlined] v8::internal::SnapshotCreatorImpl::SnapshotCreatorImpl(this=<unavailable>, isolate=<unavailable>, api_external_references=0x0000000000000000, existing_blob=0x0000000000000000, owns_isolate=<unavailable>) at snapshot.cc:870:78 [opt]
        frame #18: 0x0000000100d75888 mksnapshot`v8::internal::CreateSnapshotDataBlobInternal(function_code_handling=kClear, embedded_source=0x0000000000000000, isolate=<unavailable>, serializer_flags=(mask_ = 0)) at snapshot.cc:812:23 [opt]
        frame #19: 0x0000000100005cd4 mksnapshot`main [inlined] (anonymous namespace)::CreateSnapshotDataBlob(isolate=0x0000000108008000, embedded_source=0x0000000000000000) at mksnapshot.cc:162:28 [opt]
        frame #20: 0x0000000100005ca0 mksnapshot`main(argc=<unavailable>, argv=<unavailable>) at mksnapshot.cc:288:14 [opt]
        frame #21: 0x0000000180cdbf28 dyld`start + 2236
    
    (lldb) memory region 0x9a800008010                                                                                                                                                           [0x000009a800008000-0x000009a80003c000) r-x
    Modified memory (dirty) page list provided, 13 entries.
    Dirty pages: 0x9a800008000, 0x9a80000c000, 0x9a800010000, 0x9a800014000, 0x9a800018000, 0x9a80001c000, 0x9a800020000, 0x9a800024000, 0x9a800028000, 0x9a80002c000, 0x9a800030000, 0x9a800034000, 0x9a800038000.
    
    (lldb) x/32xw 0x9a800008010
    0x9a800008010: 0x0badc0de 0x0badc0de 0x0badc0de 0x0badc0de
    0x9a800008020: 0x0badc0de 0x0badc0de 0x0badc0de 0x0badc0de
    0x9a800008030: 0xbeadbeef 0xbeadbeef 0xbeadbeef 0xbeadbeef
    0x9a800008040: 0xbeadbeef 0xbeadbeef 0xbeadbeef 0xbeadbeef
    0x9a800008050: 0xbeadbeef 0xbeadbeef 0xbeadbeef 0xbeadbeef
    0x9a800008060: 0xbeadbeef 0xbeadbeef 0xbeadbeef 0xbeadbeef
    0x9a800008070: 0xbeadbeef 0xbeadbeef 0xbeadbeef 0xbeadbeef
    0x9a800008080: 0xbeadbeef 0xbeadbeef 0xbeadbeef 0xbeadbeef
    

    So the mksnapshot crashes when trying to write to the code page for the first builtin. It looks like the page is marked non-writable, which is strange.

  5. kvakil commented on Jan 24, 2024

    @kvakil
    Contributor

    Here's the problem:

    // pthread_jit_write_protect is only available on arm64 Mac.
    #if defined(V8_HOST_ARCH_ARM64) && \
        (defined(V8_OS_MACOS) || (defined(V8_OS_IOS) && TARGET_OS_SIMULATOR))
    #define V8_HAS_PTHREAD_JIT_WRITE_PROTECT 1
    #else
    #define V8_HAS_PTHREAD_JIT_WRITE_PROTECT 0
    #endif
    
    #if V8_HAS_PTHREAD_JIT_WRITE_PROTECT && \
        !(defined(V8_COMPRESS_POINTERS) && !defined(V8_EXTERNAL_CODE_SPACE))
    #define V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT true
    #else
    #define V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT false
    #endif

    So V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT will be false since Node's configuration doesn't enable V8_EXTERNAL_CODE_SPACE. Without V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT, the code will fallback to using an alternate way to achieve W^X by switching the page permissions:

    bool write_protect_code_memory() const {
      if (V8_HAS_PTHREAD_JIT_WRITE_PROTECT) {
        // On MacOS on ARM64 ("Apple M1"/Apple Silicon) code modification
        // protection must be used. It can be achieved by one of the following
        // approaches:
        // 1) switching memory protection between RW-RX as on other architectures
        //    => return true,
        // 2) fast W^X machinery (see V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT) which
        //    doesn not require memory protection changes => return false.
        return !V8_HEAP_USE_PTHREAD_JIT_WRITE_PROTECT;
      }
      return write_protect_code_memory_;
    }

    It looks like it's already known upstream that this configuration is broken upstream: https://chromium-review.googlesource.com/c/v8/v8/+/5123137

    Now, you could enable V8_EXTERNAL_CODE_SPACE, and then everything works fine and tests pass:

    diff --git a/configure.py b/configure.py
    index 84b016cd85..df9aebdd3f 100755
    --- a/configure.py
    +++ b/configure.py
    @@ -1502,6 +1502,7 @@ def configure_v8(o):
       o['variables']['v8_use_siphash'] = 0 if options.without_siphash else 1
       o['variables']['v8_enable_maglev'] = 1 if options.v8_enable_maglev else 0
       o['variables']['v8_enable_pointer_compression'] = 1 if options.enable_pointer_compression else 0
    +  o['variables']['v8_enable_external_code_space'] = 1 if options.enable_pointer_compression else 0
       o['variables']['v8_enable_31bit_smis_on_64bit_arch'] = 1 if options.enable_pointer_compression else 0
       o['variables']['v8_enable_shared_ro_heap'] = 0 if options.enable_pointer_compression or options.disable_shared_ro_heap else 1
       o['variables']['v8_enable_extensible_ro_snapshot'] = 0
    diff --git a/tools/v8_gypfiles/features.gypi b/tools/v8_gypfiles/features.gypi
    index c768d7a0f1..f762a5990c 100644
    --- a/tools/v8_gypfiles/features.gypi
    +++ b/tools/v8_gypfiles/features.gypi
    @@ -439,6 +439,9 @@
           ['v8_enable_shared_ro_heap==1', {
             'defines': ['V8_SHARED_RO_HEAP',],
           }],
    +      ['v8_enable_external_code_space==1', {
    +        'defines': ['V8_EXTERNAL_CODE_SPACE',],
    +      }],
           ['dcheck_always_on!=0', {
             'defines': ['DEBUG',],
           }],

    But this only works prior to #50680, since our pointer-compression build does not use the shared-isolate cage, and multi-cage pointer compression doesn't support the external code space:

    #ifdef V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE
      const Address cage_base_;
    #ifdef V8_EXTERNAL_CODE_SPACE
    // In case this configuration is necessary the code cage base must be saved too.
    #error Multi-cage pointer compression with external code space is not supported
    #endif  // V8_EXTERNAL_CODE_SPACE
    #endif  // V8_COMPRESS_POINTERS_IN_ISOLATE_CAGE

    Anyway, not sure what the correct solution here, probably the right one is to either make PtrComprCageAccessScope work with external code space (and enable external code space), or change the pointer-compression build to not use multi-cage.

  6. github-actions commented on May 24, 2026

    @github-actions
    Contributor

    This issue has been marked as stale due to 210 days of inactivity.
    It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.

  7. added
    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.
    on May 24, 2026
  8. github-actions commented on Jun 24, 2026

    @github-actions
    Contributor

    This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 240 days).
    If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleIssues and PRs marked stale due to inactivity and scheduled for automatic closure.v8 engineIssues and PRs related to the V8 dependency.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions