rules_android_ndk icon indicating copy to clipboard operation
rules_android_ndk copied to clipboard

`std::cout` isn't initialized before any user-defined static initialization

Open moshimo2019 opened this issue 2 years ago • 2 comments

clang version 14.0.7 bazel 5.3.0

The minimal source code source.cc is

#include <iostream>

struct S {
  S() { 
    // std::ios_base::Init init;
    std::cout << "static cout" << std::endl; 
  }
};

static S var_;

int main() {
  return 0;
}

BUILD.bazel

cc_binary(
    name = "source",
    srcs = ["source.cc"],
)

build command:

build --repo_env="ANDROID_NDK_HOME=/**/android-ndk-r25c" --cpu=arm64-v8a --crosstool_top=@androidndk//:toolchain --host_crosstool_top=@bazel_tools//tools/cpp:toolchain --compilation_mode=opt --copt='-O3' --cxxopt='-std=c++17'

Running the binary in development board got Segmentation fault. Uncomment the line // std::ios_base::Init init;, running is successful. It seems that the global object std::cost didn't initialized at that time. However, if I directly invoke clang by android-ndk-r25c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android23-clang --std=c++17 src/static-test.cc -o bazel-bin/static-clang.i -lstdc++, the Segmentation fault didn't happen. related issues: https://github.com/llvm/llvm-project/issues/29324 https://github.com/WebAssembly/wasi-sdk/issues/153

moshimo2019 avatar Jan 08 '24 05:01 moshimo2019

This isn't a bazel issue, nor even a bug. Static initialization order is not defined. You need explicit initialization if you care about order. That's not our choice, that's how C++ works.

DanAlbert avatar Jan 11 '24 22:01 DanAlbert

Reading through to the LLVM bug you linked, I guess LLVM has some sort of attribute to hack around that? idk how that's implemented so it may not be portable. If you want your code to be portable, don't rely on static initialization order.

In any case, that fix isn't needed in bazel, you just need a new enough NDK.

DanAlbert avatar Jan 11 '24 22:01 DanAlbert