Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gcc fails to compile with ASAN enabled #43370

Closed
SimonWoolf opened this issue Jun 10, 2022 · 13 comments
Closed

gcc fails to compile with ASAN enabled #43370

SimonWoolf opened this issue Jun 10, 2022 · 13 comments
Labels
build Issues and PRs related to build files or the CI. linux Issues and PRs related to the Linux platform.

Comments

@SimonWoolf
Copy link

Version

16.14.2

Platform

Linux simon-linuxdesktop 5.6.14-050614-generic #202005200733 SMP Wed May 20 07:38:05 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

Reproduce: attempt to build node with debug and asan enabled: ./configure --debug --enable-asan && make -j4
Same issue on ubuntu 22.04 and 20.04, and with gcc/g++ 9 and 11.

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

Every time

What is the expected behavior?

No response

What do you see instead?

...
  g++ -o /home/simon/dev/vendor/node/out/Release/obj.target/v8_libplatform/deps/v8/src/libplatform/default-worker-threads-task-runner.o ../deps/v8/src/libplatform/default-worker-threads-task-runner.cc '-D_GLIBCXX_USE_CXX11_ABI=1' '-DV8_GYP_BUILD' '-DV8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64' '-DLEAK_SANITIZER' '-DV8_USE_ADDRESS_SANITIZER' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DV8_TARGET_ARCH_X64' '-DV8_HAVE_TARGET_OS' '-DV8_TARGET_OS_LINUX' '-DV8_EMBEDDER_STRING="-node.20"' '-DENABLE_DISASSEMBLER' '-DV8_PROMISE_INTERNAL_FIELD_COUNT=1' '-DENABLE_MINOR_MC' '-DOBJECT_PRINT' '-DV8_INTL_SUPPORT' '-DV8_ATOMIC_OBJECT_FIELD_WRITES' '-DV8_ATOMIC_MARKING_STATE' '-DV8_ENABLE_LAZY_SOURCE_POSITIONS' '-DV8_USE_SIPHASH' '-DDISABLE_UNTRUSTED_CODE_MITIGATIONS' '-DV8_WIN64_UNWINDING_INFO' '-DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH' '-DV8_SNAPSHOT_COMPRESSION' '-DV8_ENABLE_WEBASSEMBLY' '-DV8_ALLOCATION_FOLDING' '-DV8_ALLOCATION_SITE_TRACKING' '-DV8_ADVANCED_BIGINT_ALGORITHMS' -I../deps/v8 -I../deps/v8/include  -fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope -pthread -Wno-unused-parameter -m64 -Wno-return-type -fno-strict-aliasing -m64 -fno-omit-frame-pointer -fdata-sections -ffunction-sections -O2 -fno-rtti -fno-exceptions -std=gnu++14 -MMD -MF /home/simon/dev/vendor/node/out/Release/.deps//home/simon/dev/vendor/node/out/Release/obj.target/v8_libplatform/deps/v8/src/libplatform/default-worker-threads-task-runner.o.d.raw   -c
In file included from ../deps/v8/src/libplatform/default-platform.cc:14:
../deps/v8/src/base/platform/platform.h: In static member function ‘static v8::base::Stack::StackSlot v8::base::Stack::GetRealStackAddressForSlot(v8::base::Stack::StackSlot)’:
../deps/v8/src/base/platform/platform.h:477:16: error: operands to ?: have different types ‘char*’ and ‘v8::base::Stack::StackSlot’
  476 |     return real_frame
      |            ~~~~~~~~~~
  477 |                ? (static_cast<char*>(real_frame) + kAsanRealFrameOffsetBytes)
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  478 |                : slot;
      |                ~~~~~~
../deps/v8/src/base/platform/platform.h:478:18: error: conversion from ‘v8::base::Stack::StackSlot’ to ‘char*’ is ambiguous
  478 |                : slot;
      |                  ^~~~
../deps/v8/src/base/platform/platform.h:450:5: note: candidate: ‘v8::base::Stack::StackSlot::operator void*() const’ <near match>
  450 |     operator void*() const { return reinterpret_cast<void*>(value); }
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:450:5: note:   no known conversion from ‘void*’ to ‘char*’
../deps/v8/src/base/platform/platform.h:451:5: note: candidate: ‘v8::base::Stack::StackSlot::operator uintptr_t() const’ <near match>
  451 |     operator uintptr_t() const { return value; }  // NOLINT
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:451:5: note:   no known conversion from ‘uintptr_t’ {aka ‘long unsigned int’} to ‘char*’
In file included from ../deps/v8/src/libplatform/default-worker-threads-task-runner.h:14,
                 from ../deps/v8/src/libplatform/default-worker-threads-task-runner.cc:5:
../deps/v8/src/base/platform/platform.h: In static member function ‘static v8::base::Stack::StackSlot v8::base::Stack::GetRealStackAddressForSlot(v8::base::Stack::StackSlot)’:
../deps/v8/src/base/platform/platform.h:477:16: error: operands to ?: have different types ‘char*’ and ‘v8::base::Stack::StackSlot’
  476 |     return real_frame
      |            ~~~~~~~~~~
  477 |                ? (static_cast<char*>(real_frame) + kAsanRealFrameOffsetBytes)
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  478 |                : slot;
      |                ~~~~~~
../deps/v8/src/base/platform/platform.h:478:18: error: conversion from ‘v8::base::Stack::StackSlot’ to ‘char*’ is ambiguous
  478 |                : slot;
      |                  ^~~~
../deps/v8/src/base/platform/platform.h:450:5: note: candidate: ‘v8::base::Stack::StackSlot::operator void*() const’ <near match>
  450 |     operator void*() const { return reinterpret_cast<void*>(value); }
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:450:5: note:   no known conversion from ‘void*’ to ‘char*’
../deps/v8/src/base/platform/platform.h:451:5: note: candidate: ‘v8::base::Stack::StackSlot::operator uintptr_t() const’ <near match>
  451 |     operator uintptr_t() const { return value; }  // NOLINT
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:451:5: note:   no known conversion from ‘uintptr_t’ {aka ‘long unsigned int’} to ‘char*’
  g++ -o /home/simon/dev/vendor/node/out/Release/obj.target/v8_libplatform/deps/v8/src/libplatform/delayed-task-queue.o ../deps/v8/src/libplatform/delayed-task-queue.cc '-D_GLIBCXX_USE_CXX11_ABI=1' '-DV8_GYP_BUILD' '-DV8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64' '-DLEAK_SANITIZER' '-DV8_USE_ADDRESS_SANITIZER' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DV8_TARGET_ARCH_X64' '-DV8_HAVE_TARGET_OS' '-DV8_TARGET_OS_LINUX' '-DV8_EMBEDDER_STRING="-node.20"' '-DENABLE_DISASSEMBLER' '-DV8_PROMISE_INTERNAL_FIELD_COUNT=1' '-DENABLE_MINOR_MC' '-DOBJECT_PRINT' '-DV8_INTL_SUPPORT' '-DV8_ATOMIC_OBJECT_FIELD_WRITES' '-DV8_ATOMIC_MARKING_STATE' '-DV8_ENABLE_LAZY_SOURCE_POSITIONS' '-DV8_USE_SIPHASH' '-DDISABLE_UNTRUSTED_CODE_MITIGATIONS' '-DV8_WIN64_UNWINDING_INFO' '-DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH' '-DV8_SNAPSHOT_COMPRESSION' '-DV8_ENABLE_WEBASSEMBLY' '-DV8_ALLOCATION_FOLDING' '-DV8_ALLOCATION_SITE_TRACKING' '-DV8_ADVANCED_BIGINT_ALGORITHMS' -I../deps/v8 -I../deps/v8/include  -fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope -pthread -Wno-unused-parameter -m64 -Wno-return-type -fno-strict-aliasing -m64 -fno-omit-frame-pointer -fdata-sections -ffunction-sections -O2 -fno-rtti -fno-exceptions -std=gnu++14 -MMD -MF /home/simon/dev/vendor/node/out/Release/.deps//home/simon/dev/vendor/node/out/Release/obj.target/v8_libplatform/deps/v8/src/libplatform/delayed-task-queue.o.d.raw   -c
make[1]: *** [tools/v8_gypfiles/v8_libplatform.target.mk:158: /home/simon/dev/vendor/node/out/Release/obj.target/v8_libplatform/deps/v8/src/libplatform/default-worker-threads-task-runner.o] Error 1
make[1]: *** Waiting for unfinished jobs....
make[1]: *** [tools/v8_gypfiles/v8_libplatform.target.mk:158: /home/simon/dev/vendor/node/out/Release/obj.target/v8_libplatform/deps/v8/src/libplatform/default-platform.o] Error 1
rm c811dc5233a4a706afbbaa1b86deb16c3131dc34.intermediate
make: *** [Makefile:113: node] Error 2

Additional information

No response

@aduh95
Copy link
Contributor

aduh95 commented Jun 10, 2022

Can you try with Node.js 16.15.1? This GitHub Actions that compiles and test Node.js with ASAN enabled is successful: https://github.com/nodejs/node/runs/6699505955?check_suite_focus=true.

@SimonWoolf
Copy link
Author

SimonWoolf commented Jun 10, 2022

Unfortunately I get the same result with node 16.15.1.

I notice that that github action is using clang wheras I'm gcc, is it possible asan builds have never worked with gcc? I'll try forcing it to build with clang and report back.

Edit: confirmed

@F3n67u
Copy link
Member

F3n67u commented Jun 11, 2022

I can reproduce when running ./configure --debug --enable-asan && make -j16.

$ ./configure --debug --enable-asan && make -j16
<....omit lot of g++ output>
g++ -o /workspace/node/out/Release/obj.target/v8_libbase/deps/v8/src/base/numbers/dtoa.o ../deps/v8/src/base/numbers/dtoa.cc '-D_GLIBCXX_USE_CXX11_ABI=1' '-DNODE_OPENSSL_CONF_NAME=nodejs_conf' '-DNODE_OPENSSL_HAS_QUIC' '-DV8_GYP_BUILD' '-DV8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64' '-DLEAK_SANITIZER' '-DV8_USE_ADDRESS_SANITIZER' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DV8_TARGET_ARCH_X64' '-DV8_HAVE_TARGET_OS' '-DV8_TARGET_OS_LINUX' '-DV8_EMBEDDER_STRING="-node.8"' '-DENABLE_DISASSEMBLER' '-DV8_PROMISE_INTERNAL_FIELD_COUNT=1' '-DV8_SHORT_BUILTIN_CALLS' '-DOBJECT_PRINT' '-DV8_INTL_SUPPORT' '-DV8_ATOMIC_OBJECT_FIELD_WRITES' '-DV8_ENABLE_LAZY_SOURCE_POSITIONS' '-DV8_USE_SIPHASH' '-DV8_SHARED_RO_HEAP' '-DV8_WIN64_UNWINDING_INFO' '-DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH' '-DV8_SNAPSHOT_COMPRESSION' '-DV8_ENABLE_WEBASSEMBLY' '-DV8_ENABLE_JAVASCRIPT_PROMISE_HOOKS' '-DV8_ALLOCATION_FOLDING' '-DV8_ALLOCATION_SITE_TRACKING' '-DV8_SCRIPTORMODULE_LEGACY_LIFETIME' '-DV8_ADVANCED_BIGINT_ALGORITHMS' '-DBUILDING_V8_BASE_SHARED' -I../deps/v8 -I../deps/v8/include  -fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope -pthread -Wno-unused-parameter -m64 -Wno-return-type -fno-strict-aliasing -m64 -fno-omit-frame-pointer -fdata-sections -ffunction-sections -O2 -fno-rtti -fno-exceptions -std=gnu++17 -MMD -MF /workspace/node/out/Release/.deps//workspace/node/out/Release/obj.target/v8_libbase/deps/v8/src/base/numbers/dtoa.o.d.raw   -c
In file included from ../deps/v8/src/base/file-utils.cc:10:
../deps/v8/src/base/platform/platform.h: In static member function ‘static v8::base::Stack::StackSlot v8::base::Stack::GetRealStackAddressForSlot(v8::base::Stack::StackSlot)’:
../deps/v8/src/base/platform/platform.h:635:16: error: operands to ?: have different types ‘char*’ and ‘v8::base::Stack::StackSlot’
  634 |     return real_frame
      |            ~~~~~~~~~~
  635 |                ? (static_cast<char*>(real_frame) + kAsanRealFrameOffsetBytes)
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  636 |                : slot;
      |                ~~~~~~
../deps/v8/src/base/platform/platform.h:636:18: error: conversion from ‘v8::base::Stack::StackSlot’ to ‘char*’ is ambiguous
  636 |                : slot;
      |                  ^~~~
../deps/v8/src/base/platform/platform.h:608:5: note: candidate: ‘v8::base::Stack::StackSlot::operator void*() const’ <near match>
  608 |     operator void*() const { return reinterpret_cast<void*>(value); }
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:608:5: note:   no known conversion from ‘void*’ to ‘char*’
../deps/v8/src/base/platform/platform.h:609:5: note: candidate: ‘v8::base::Stack::StackSlot::operator uintptr_t() const’ <near match>
  609 |     operator uintptr_t() const { return value; }  // NOLINT
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:609:5: note:   no known conversion from ‘uintptr_t’ {aka ‘long unsigned int’} to ‘char*’
  g++ -o /workspace/node/out/Release/obj.target/v8_libbase/deps/v8/src/base/numbers/fast-dtoa.o ../deps/v8/src/base/numbers/fast-dtoa.cc '-D_GLIBCXX_USE_CXX11_ABI=1' '-DNODE_OPENSSL_CONF_NAME=nodejs_conf' '-DNODE_OPENSSL_HAS_QUIC' '-DV8_GYP_BUILD' '-DV8_TYPED_ARRAY_MAX_SIZE_IN_HEAP=64' '-DLEAK_SANITIZER' '-DV8_USE_ADDRESS_SANITIZER' '-D__STDC_FORMAT_MACROS' '-DOPENSSL_NO_PINSHARED' '-DOPENSSL_THREADS' '-DV8_TARGET_ARCH_X64' '-DV8_HAVE_TARGET_OS' '-DV8_TARGET_OS_LINUX' '-DV8_EMBEDDER_STRING="-node.8"' '-DENABLE_DISASSEMBLER' '-DV8_PROMISE_INTERNAL_FIELD_COUNT=1' '-DV8_SHORT_BUILTIN_CALLS' '-DOBJECT_PRINT' '-DV8_INTL_SUPPORT' '-DV8_ATOMIC_OBJECT_FIELD_WRITES' '-DV8_ENABLE_LAZY_SOURCE_POSITIONS' '-DV8_USE_SIPHASH' '-DV8_SHARED_RO_HEAP' '-DV8_WIN64_UNWINDING_INFO' '-DV8_ENABLE_REGEXP_INTERPRETER_THREADED_DISPATCH' '-DV8_SNAPSHOT_COMPRESSION' '-DV8_ENABLE_WEBASSEMBLY' '-DV8_ENABLE_JAVASCRIPT_PROMISE_HOOKS' '-DV8_ALLOCATION_FOLDING' '-DV8_ALLOCATION_SITE_TRACKING' '-DV8_SCRIPTORMODULE_LEGACY_LIFETIME' '-DV8_ADVANCED_BIGINT_ALGORITHMS' '-DBUILDING_V8_BASE_SHARED' -I../deps/v8 -I../deps/v8/include  -fno-omit-frame-pointer -fsanitize=address -fsanitize-address-use-after-scope -pthread -Wno-unused-parameter -m64 -Wno-return-type -fno-strict-aliasing -m64 -fno-omit-frame-pointer -fdata-sections -ffunction-sections -O2 -fno-rtti -fno-exceptions -std=gnu++17 -MMD -MF /workspace/node/out/Release/.deps//workspace/node/out/Release/obj.target/v8_libbase/deps/v8/src/base/numbers/fast-dtoa.o.d.raw   -c
In file included from ../deps/v8/src/base/virtual-address-space.h:11,
                 from ../deps/v8/src/base/emulated-virtual-address-subspace.h:13,
                 from ../deps/v8/src/base/emulated-virtual-address-subspace.cc:5:
../deps/v8/src/base/platform/platform.h: In static member function ‘static v8::base::Stack::StackSlot v8::base::Stack::GetRealStackAddressForSlot(v8::base::Stack::StackSlot)’:
../deps/v8/src/base/platform/platform.h:635:16: error: operands to ?: have different types ‘char*’ and ‘v8::base::Stack::StackSlot’
  634 |     return real_frame
      |            ~~~~~~~~~~
  635 |                ? (static_cast<char*>(real_frame) + kAsanRealFrameOffsetBytes)
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  636 |                : slot;
      |                ~~~~~~
../deps/v8/src/base/platform/platform.h:636:18: error: conversion from ‘v8::base::Stack::StackSlot’ to ‘char*’ is ambiguous
  636 |                : slot;
      |                  ^~~~
../deps/v8/src/base/platform/platform.h:608:5: note: candidate: ‘v8::base::Stack::StackSlot::operator void*() const’ <near match>
  608 |     operator void*() const { return reinterpret_cast<void*>(value); }
      |     ^~~~~~~~
make[1]: *** [tools/v8_gypfiles/v8_libbase.target.mk:194: /workspace/node/out/Release/obj.target/v8_libbase/deps/v8/src/base/file-utils.o] Error 1
make[1]: *** Waiting for unfinished jobs....
../deps/v8/src/base/platform/platform.h:608:5: note:   no known conversion from ‘void*’ to ‘char*’
../deps/v8/src/base/platform/platform.h:609:5: note: candidate: ‘v8::base::Stack::StackSlot::operator uintptr_t() const’ <near match>
  609 |     operator uintptr_t() const { return value; }  // NOLINT
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:609:5: note:   no known conversion from ‘uintptr_t’ {aka ‘long unsigned int’} to ‘char*’
make[1]: *** [tools/v8_gypfiles/v8_libbase.target.mk:194: /workspace/node/out/Release/obj.target/v8_libbase/deps/v8/src/base/emulated-virtual-address-subspace.o] Error 1
In file included from ../deps/v8/src/base/logging.cc:13:
../deps/v8/src/base/platform/platform.h: In static member function ‘static v8::base::Stack::StackSlot v8::base::Stack::GetRealStackAddressForSlot(v8::base::Stack::StackSlot)’:
../deps/v8/src/base/platform/platform.h:635:16: error: operands to ?: have different types ‘char*’ and ‘v8::base::Stack::StackSlot’
  634 |     return real_frame
      |            ~~~~~~~~~~
  635 |                ? (static_cast<char*>(real_frame) + kAsanRealFrameOffsetBytes)
      |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  636 |                : slot;
      |                ~~~~~~
../deps/v8/src/base/platform/platform.h:636:18: error: conversion from ‘v8::base::Stack::StackSlot’ to ‘char*’ is ambiguous
  636 |                : slot;
      |                  ^~~~
../deps/v8/src/base/platform/platform.h:608:5: note: candidate: ‘v8::base::Stack::StackSlot::operator void*() const’ <near match>
  608 |     operator void*() const { return reinterpret_cast<void*>(value); }
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:608:5: note:   no known conversion from ‘void*’ to ‘char*’
../deps/v8/src/base/platform/platform.h:609:5: note: candidate: ‘v8::base::Stack::StackSlot::operator uintptr_t() const’ <near match>
  609 |     operator uintptr_t() const { return value; }  // NOLINT
      |     ^~~~~~~~
../deps/v8/src/base/platform/platform.h:609:5: note:   no known conversion from ‘uintptr_t’ {aka ‘long unsigned int’} to ‘char*’
make[1]: *** [tools/v8_gypfiles/v8_libbase.target.mk:194: /workspace/node/out/Release/obj.target/v8_libbase/deps/v8/src/base/logging.o] Error 1
make: *** [Makefile:113: node] Error 2

Error happened at:

// Returns the real stack frame if slot is part of a fake frame, and slot
// otherwise.
static StackSlot GetRealStackAddressForSlot(StackSlot slot) {
#ifdef V8_USE_ADDRESS_SANITIZER
// ASAN fetches the real stack deeper in the __asan_addr_is_in_fake_stack()
// call (precisely, deeper in __asan_stack_malloc_()), which results in a
// real frame that could be outside of stack bounds. Adjust for this
// impreciseness here.
constexpr size_t kAsanRealFrameOffsetBytes = 32;
void* real_frame = __asan_addr_is_in_fake_stack(
__asan_get_current_fake_stack(), slot, nullptr, nullptr);
return real_frame
? (static_cast<char*>(real_frame) + kAsanRealFrameOffsetBytes)
: slot;
#endif // V8_USE_ADDRESS_SANITIZER
return slot;
}

After switching to clang/clang++, then build successfully.

$ export CC=clang
$ export CXX=clang++
$ export LINK=clang++
$ ./configure --debug --enable-asan && make -j16
  <....omit lot of clang++ output>
  clang++ -o /workspace/node/out/Debug/node -fsanitize=address -pthread -rdynamic -m64 /workspace/node/out/Debug/obj.target/node_text_start/src/large_pages/node_text_start.o -Wl,--whole-archive /workspace/node/out/Debug/obj.target/libnode.a /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_base_without_compiler.a -Wl,--no-whole-archive -Wl,--whole-archive /workspace/node/out/Debug/obj.target/deps/zlib/libzlib.a -Wl,--no-whole-archive -Wl,--whole-archive /workspace/node/out/Debug/obj.target/deps/uv/libuv.a -Wl,--no-whole-archive -Wl,-z,noexecstack -Wl,--whole-archive /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_snapshot.a -Wl,--no-whole-archive -Wl,-z,relro -Wl,-z,now -Wl,--whole-archive,/workspace/node/out/Debug/obj.target/deps/openssl/libopenssl.a -Wl,--no-whole-archive -pthread  -Wl,--start-group /workspace/node/out/Debug/obj.target/node/src/node_main.o /workspace/node/out/Debug/obj.target/node/gen/node_snapshot.o /workspace/node/out/Debug/obj.target/deps/histogram/libhistogram.a /workspace/node/out/Debug/obj.target/deps/uvwasi/libuvwasi.a /workspace/node/out/Debug/obj.target/libnode.a /workspace/node/out/Debug/obj.target/libnode_text_start.a /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_snapshot.a /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_libplatform.a /workspace/node/out/Debug/obj.target/tools/icu/libicui18n.a /workspace/node/out/Debug/obj.target/deps/zlib/libzlib.a /workspace/node/out/Debug/obj.target/deps/llhttp/libllhttp.a /workspace/node/out/Debug/obj.target/deps/cares/libcares.a /workspace/node/out/Debug/obj.target/deps/uv/libuv.a /workspace/node/out/Debug/obj.target/deps/nghttp2/libnghttp2.a /workspace/node/out/Debug/obj.target/deps/brotli/libbrotli.a /workspace/node/out/Debug/obj.target/deps/openssl/libopenssl.a /workspace/node/out/Debug/obj.target/deps/ngtcp2/libngtcp2.a /workspace/node/out/Debug/obj.target/deps/ngtcp2/libnghttp3.a /workspace/node/out/Debug/obj.target/tools/icu/libicuucx.a /workspace/node/out/Debug/obj.target/tools/icu/libicudata.a /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_base_without_compiler.a /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_libbase.a /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_zlib.a /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_compiler.a /workspace/node/out/Debug/obj.target/tools/v8_gypfiles/libv8_initializers.a -latomic -lm -ldl -Wl,--end-group
rm 010fc3fce712b2de6fd928cc15b58656333c3aaf.intermediate a665f57085c97becc8e697d5d0d22eab075bd2c3.intermediate 637454bf7bda9fb424d235143ccd28cd1a54c56d.intermediate 7928751cc4288ed548e4b41355b615a941ac7bcf.intermediate
if [ ! -r node_g ] || [ ! -L node_g ]; then \
  ln -fs out/Debug/node node_g; fi

Env Info

$ npx -y envinfo

  System:
    OS: Linux 5.16 Ubuntu 20.04.4 LTS (Focal Fossa)
    CPU: (16) x64 AMD EPYC 7B13
    Memory: 34.34 GB / 62.80 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash
  Utilities:
    GCC: 9.4.0 - /usr/bin/gcc
    Clang: 15.0.0 - /usr/bin/clang

Node source lastest commit

$ git --no-pager log  -n1
commit cb7e854c776d366fed74ec3edf082aea0e723a6f (HEAD -> f3n67u/node-doesn-t-compile-with-43370, origin/master, origin/HEAD, master)
Author: Daeyeon Jeong <daeyeon.dev@gmail.com>
Date:   Fri Jun 10 17:24:50 2022 +0900

    doc: fix typo in globals.md
    
    Use apostrophe for possessive.
    
    Signed-off-by: Daeyeon Jeong daeyeon.dev@gmail.com
    
    PR-URL: https://github.com/nodejs/node/pull/43365
    Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
    Reviewed-By: Darshan Sen <raisinten@gmail.com>
    Reviewed-By: Akhil Marsonya <akhil.marsonya27@gmail.com>
    Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
    Reviewed-By: Luigi Pinca <luigipinca@gmail.com>

@aduh95 aduh95 changed the title Node 16 doesn't compile with ASAN enabled gcc fails to compile with ASAN enabled Jun 11, 2022
@aduh95
Copy link
Contributor

aduh95 commented Jun 11, 2022

It looks like cliang was introduced on the GitHub Actions CI on #32776, although at this time it seems that gcc was able to compile an ASAN build, although it was taking a long time.
@nodejs/build do we want to document that Clang is required for ASAN builds or can we fix the underlying issue?

@bnoordhuis
Copy link
Member

This is an upstream V8 issue but there's probably an easy fix:

diff --git a/deps/v8/src/base/platform/platform.h b/deps/v8/src/base/platform/platform.h
index e801ec78c26..55de08cc5fc 100644
--- a/deps/v8/src/base/platform/platform.h
+++ b/deps/v8/src/base/platform/platform.h
@@ -632,7 +632,7 @@ class V8_BASE_EXPORT Stack {
     void* real_frame = __asan_addr_is_in_fake_stack(
         __asan_get_current_fake_stack(), slot, nullptr, nullptr);
     return real_frame
-               ? (static_cast<char*>(real_frame) + kAsanRealFrameOffsetBytes)
+               ? StackSlot(static_cast<char*>(real_frame) + kAsanRealFrameOffsetBytes)
                : slot;
 #endif  // V8_USE_ADDRESS_SANITIZER
     return slot;

I speculate clang applies an implicit conversion and gcc does not.

@F3n67u
Copy link
Member

F3n67u commented Jun 11, 2022

I tried to apply @bnoordhuis's suggest fix and rerun the ASAN build using GCC, but it was never successful because of running out of memory even if the total memory is greater than 32GB. The running out of memory problem when using GCC to run an ASAN build is also mentioned at #32776.

Maybe we should document that Clang is required for ASAN builds just like @aduh95 suggest?

@F3n67u F3n67u added build Issues and PRs related to build files or the CI. linux Issues and PRs related to the Linux platform. labels Jun 11, 2022
@bnoordhuis
Copy link
Member

Does that out of memory error happen when linking? If yes, this might help:

diff --git a/common.gypi b/common.gypi
index ecb5dd907f2..38f83503be3 100644
--- a/common.gypi
+++ b/common.gypi
@@ -347,10 +347,11 @@
           '-fno-omit-frame-pointer',
           '-fsanitize=address',
           '-fsanitize-address-use-after-scope',
+          '-fuse-ld=lld',
         ],
         'defines': [ 'LEAK_SANITIZER', 'V8_USE_ADDRESS_SANITIZER' ],
         'cflags!': [ '-fomit-frame-pointer' ],
-        'ldflags': [ '-fsanitize=address' ],
+        'ldflags': [ '-fsanitize=address', '-fuse-ld=lld' ],
       }],
       ['asan == 1 and OS == "mac"', {
         'xcode_settings': {

Replace lld with gold to use the gold linker.

@F3n67u
Copy link
Member

F3n67u commented Jun 11, 2022

@bnoordhuis Thank you for your help! It's late night in my timezone, I will try your solution tomorrow and report back.

@F3n67u
Copy link
Member

F3n67u commented Jun 13, 2022

@bnoordhuis I failed to make GCC ASAN build work, It fails either GCC being killed or disk space not enough. It seems don't happen during link stage, the command is still g++ -o when error happened. (I am not sure, I don't know how to differentiate when is link, I am not familiar with the c++ toolchain)

I tried the asan build in the Gitpod WebIDE container, it's less powerful than I thought( I thought it give me 64G memory and 16Core, but it seems it is shared by many instances). I thought I will not help to make any progress to forward this issue, I don't have a powerful Linux computer to verify those things. It will be great if anyone who has a powerful Linux computer could chime in

I found the following points:

  • Even though I have not changed any code, I could make GCC ASAN build successful on my local Mac using node master code.
  • In Linux, clang consumes less memory and disk space and is faster than GCC, when building ASAN via GCC, out directory could be 25G
  • If anyone needs to build an ASAN version of Node Core, I will suggest preferring clang over GCC according to my experience.

@bnoordhuis
Copy link
Member

Thanks for the update, @F3n67u. I agree it makes sense to recommend/require clang if gcc is that problematic.

@j1elo
Copy link

j1elo commented Dec 20, 2022

Hi, I'll chime in to comment my experience with this. I don't see any reason to require clang, or an alternative linker, given that the default tools on Linux (gcc and ld) work properly, provided that the machine has enough resources (and the code fix from #43370 (comment) is applied).

I've been following the instructions from BUILDING.md, which doesn't even mention clang, lld, or gold, so I didn't think of using them. Maybe clang or an alternative linker would require much less space, I don't know... but with GCC and ld, a complete Debug build of Node.js (with ./configure --debug) will take:

  • Approx. 30GB of disk space.
  • Approx. 8GB of memory for each linked executable.

The second point is the most problematic. Given parallel execution (with either of ./configure --ninja or make -j$(nproc)), this means that linking 4 executables at the same time (for a 4 core CPU) will require upwards of 32GB of memory. My machine has 16GB, so the kernel Out Of Memory (OOM) killer would terminate the ld process. Here, the options are to re-run with make -j1, which only requires around 8GB of free memory; or growing the swap partition to ensure enough memory is available. I tested both options and they worked fine (albeit obviously it's always better to avoid using swap).

Both of above points happen because several (unnecessary?) binaries are compiled, and they are multi-GB each:

  • mksnapshot
  • node_mksnapshot
  • embedtest
  • cctest
  • node

For a dev trying to report an issue and wanting to run a Debug build of Node.js, only the last one is useful (and it's also the only one installed with make install).

Finally, yes, I can confirm that the Address Sanitizer (./configure --enable-asan) build does need the patch mentioned in comment #43370 (comment) (tested with and without, with GCC 9.4.0; only with the patch it compiled successfully).

To wrap, some questions to advance on this:

  • Is it possible to somehow instruct the build system to only build the node binary, thus greatly reducing disk and memory requirements? (but still make a complete debug build, aka. V8; otherwise I already know about ./configure --debug-node)
  • Alternatively, is it possible to run the compilation and link steps separately? If the above answer is a "no", a good workaround would be to run the compilation steps with -j$(nproc) and the link steps with -j1.
  • What are the disk/memory requirements when using lld or gold, for someone who is using those instead of ld?
  • How could the required patch be integrated? Can it be applied as a patch to the vendored dependency, while the actual patch is proposed & accepted upstream (which could take a while)?

@bnoordhuis
Copy link
Member

Is it possible to somehow instruct the build system to only build the node binary

No. You can instruct make to omit cctest and embedtest but the mksnapshot binaries are prerequisites.

make node -C out BUILDTYPE=Release, IIRC. BUILDTYPE=Debug + ASAN may be too slow to be usable.

How could the required patch be integrated?

It needs to be upstreamed first. We don't, as a rule, float patches that haven't been accepted upstream.

Feel free to upstream it, no attribution needed.

@bnoordhuis
Copy link
Member

I'm going to close this. The OOM errors can perhaps be avoided by serializing the link step, see #45949 (comment).

@bnoordhuis bnoordhuis closed this as not planned Won't fix, can't repro, duplicate, stale Dec 29, 2022
RaisinTen added a commit to RaisinTen/node that referenced this issue Mar 30, 2023
Original commit message:

    Fix compilation error in platform.h for ASAN
    The last two operands of the conditional expression needs to be
    of the same type to compile.

    Change-Id: Ib6cba4acb1238394910c650c776a7fd1ee93721e
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4306802
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#86235}

Refs: v8/v8@cb30b8e
Refs: nodejs#43370
Signed-off-by: Darshan Sen <raisinten@gmail.com>
RaisinTen added a commit to RaisinTen/node that referenced this issue Apr 3, 2023
Original commit message:

    Fix compilation error in platform.h for ASAN
    The last two operands of the conditional expression needs to be
    of the same type to compile.

    Change-Id: Ib6cba4acb1238394910c650c776a7fd1ee93721e
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4306802
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#86235}

Refs: v8/v8@cb30b8e
Refs: nodejs#43370
Signed-off-by: Darshan Sen <raisinten@gmail.com>
RaisinTen added a commit that referenced this issue Apr 5, 2023
Original commit message:

    Fix compilation error in platform.h for ASAN
    The last two operands of the conditional expression needs to be
    of the same type to compile.

    Change-Id: Ib6cba4acb1238394910c650c776a7fd1ee93721e
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4306802
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#86235}

Refs: v8/v8@cb30b8e
Refs: #43370
Signed-off-by: Darshan Sen <raisinten@gmail.com>
PR-URL: #47307
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
RafaelGSS pushed a commit that referenced this issue Apr 7, 2023
Original commit message:

    Fix compilation error in platform.h for ASAN
    The last two operands of the conditional expression needs to be
    of the same type to compile.

    Change-Id: Ib6cba4acb1238394910c650c776a7fd1ee93721e
    Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4306802
    Commit-Queue: Joyee Cheung <joyee@igalia.com>
    Reviewed-by: Michael Lippautz <mlippautz@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#86235}

Refs: v8/v8@cb30b8e
Refs: #43370
Signed-off-by: Darshan Sen <raisinten@gmail.com>
PR-URL: #47307
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
build Issues and PRs related to build files or the CI. linux Issues and PRs related to the Linux platform.
Projects
None yet
Development

No branches or pull requests

5 participants