-
Notifications
You must be signed in to change notification settings - Fork 191
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
[libc++abi] Disable undesired attempts at opening file descriptors #418
base: main
Are you sure you want to change the base?
Conversation
When building for a web target, there is no stderr. However, the abort implementation in the current CXXABI runtime is implemented with writes to stderr. Since the constructors for default objects call abort, these are rightfully not optimised out from the compiler. However, it is hardly sensible in my opinion to have to include a whole WASI runtime implementation in the browser just to handle more informative aborts by default. To prevent this, compile the cxxabi runtime with NDEBUG and CXXABI_BAREMETAL flags. This is not enough though, as the compiler will still try to instantiate __libcpp_verbose_abort from the stdcxx library. To prevent the compiler from instantiating __libcpp_verbose_abort, clean fix for this is to consistently set _LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT=0 in the __availability header. This requires forking or patching LLVM.
@@ -185,6 +185,7 @@ build/compiler-rt.BUILT: build/llvm.BUILT | |||
# $(3): the name of the target being built for | |||
# $(4): extra compiler flags to pass | |||
LIBCXX_CMAKE_FLAGS = \ | |||
-DNDEBUG=1 \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is -DCMAKE_BUILD_TYPE=RelWithDebInfo
below not enough to get this defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, from further inspection it looks like it. This flag isn't piped through to make
. See the thread for why I included it in the first place.
Can you perhaps mention in the title and/or description that this change relates specifically the libc++abi? (Perhaps prefix the title with |
And just to clarify: this PR does not fully solve #401 because of |
This is the patch that needs to be applied to llvm to be able to run stdlib code bare metal in the browser. This alone is sufficient to fix #401 - at least for C++.
For me it looks like setting I noticed from Regarding A full solution would need to both compile |
@@ -205,7 +206,8 @@ LIBCXX_CMAKE_FLAGS = \ | |||
-DLIBCXX_ENABLE_SHARED:BOOL=$(2) \ | |||
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL=OFF \ | |||
-DLIBCXX_ENABLE_EXCEPTIONS:BOOL=OFF \ | |||
-DLIBCXX_ENABLE_FILESYSTEM:BOOL=ON \ | |||
-DLIBCXX_ENABLE_FILESYSTEM:BOOL=OFF \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why?
does this disable the following message?
while i agree a library should not use stderr in general, |
answering myself, it's easy for apps to override "abort_message". extern "C" void abort_message(const char *fmt, ...)
{
} isn't it enough for your purpose? |
I think I had tried something similar but my signature might not have matched properly. I'd need to test this again, not sure when I'll have time. |
Going back to the OP I think I disagree with "When building for a web target, there is no stderr." Running WASI programs on the web will likely require implementing stderr and there seems to be a reasonable implementation which is to map it to |
Whilst I agree with that, I believe that it should be responsibility of a higher level framework. I find it a bit puzzling that I cannot build a bare metal binary with a barebone SDK without having to run through all these hoops. I know most users will probably want to go with emscripten, but I believe if I don't opt in to any standard I/O, I shouldn't have to override functions from the app in order for my binary not to fail unexpectedly trying to open I/O. |
Unless I'm misunderstanding and you're suggesting that somehow you could provide stderr emulation in console natively without the need for external boilerplate from the app |
I agree it should be possible to build WASI programs with no stdio at all, but I also think that most WASI implementations (such as JCO or emscripten on the web) will choose to support them. Wouldn't debugging be extremely hard without stderr? How would C's |
Any time you want to run a WASI program on the web you will need some kind of boilerplate, right? Likely quite a lot since the web doesn't naively support WASI. Take a look at something like JCO or emscripten. Even if you do the absolute minimum I imagine that you would probably want to include stdio.. since it will make debugging so much easier, and without that you can't even run hello_world.c right? |
again, I think this is only partially true isn't it? The web supports WebAssembly, and what I was arguing was that I should be able to compile / load pure WebAssembly code written in C++ without having to hack around llvm and WASI. I think maybe my use case was a bit esoteric, but what I was doing was using a purely JavaScript program and importing a C++ set of library functions written in C++ and unit-tested in C++, so I could deliver a very lightweight web page that could crunch numbers at high performance for me. I didn't need stdout for that. In general, if I want to use whatever e.g. scientific computation library written in C++, I would expect to be able to strip out the logging and just chuck it in my webpage. Using emscripten for such a use case felt to me a bit overkill, and in fact with this simple modification I was able to achieve my goal. I felt that more people would benefit from being able to do this easily. |
It sounds like you want something different to wasi-sdk. Perhaps some kind a bare metal wasm SDK where no WASI imports are used? In that mode you probably would want to use wasm32-unknown-unknown, rather than wasm32-unknown-wasi. WASI is literally all about system APIs (aka imports). |
I'm sympathetic to @infinitesnow's issue here: in the past I've also wanted to use wasi-sdk to emit very minimal WebAssembly modules and it can be tough and frustrating to figure out what's going wrong. I don't know if turning off C++ abort printing for everyone is the right approach; it seems like the average user probably would want to see those messages, right? Let's see if we can't get to the bottom of this with some questions to @infinitesnow and either merge a modified version or close this:
|
When building for a web target, there is no stderr. However, the abort implementation in the current CXXABI runtime is implemented with writes to stderr.
Since the constructors for default objects call abort, these are rightfully not optimised out from the compiler. However, it is hardly sensible in my opinion to have to include a whole WASI runtime implementation in the browser just to handle more informative aborts by default.
To prevent this, compile the cxxabi runtime with
NDEBUG
andCXXABI_BAREMETAL
flags.This is not enough though, as the compiler will still try to instantiate
__libcpp_verbose_abort
from the stdcxx library. To prevent the compiler from instantiating__libcpp_verbose_abort
, clean fix for this is to consistently set_LIBCPP_AVAILABILITY_HAS_VERBOSE_ABORT=0
in the__availability
header. This requires forking or patching LLVM.