-
Notifications
You must be signed in to change notification settings - Fork 1.7k
[vm/ffi] Investigate potential incompatibilities from statically linking libc++ #38141
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
Comments
This is reproduced even when the executable is C: Makefile:
main.c: #include <dlfcn.h>
int main() {
void (*foo)() = (void (*)())dlsym(dlopen("./foo.so", RTLD_LAZY), "foo");
foo();
return 0;
} |
It appears to be an issue with the manner in which the Dart binary statically links in Your library is allocating the exception via You can see that GCC's implementation of |
We should not symbols from our statically-linked version of We also need to think deeply about other ways this issue can surface. For example, does There also may be TLS issues with multiple copies of |
/cc @mkustermann |
That... sounds scary. Nothing you can fix quickly, I suppose? |
I'm not sure whether we can fix it quickly, but you can work around it by using our toolchain. A full checkout of the Dart SDK with |
@sjindel-google Thanks. Long term, ofc, we'd prefer to use our standard dynamic libs from our distribution channel. However, if we'd make a special version for Dart, it might also be an option to link the std lib statically into our lib, right? |
In principle yes, however even with |
Flutter may not have this issue, but if they do, they (and other embedders) need to address it separately. |
Issue #38141 On Windows and OSX, we dynamically link against libc++, so there is no issue. On Android we already hide symbols from libc++. Change-Id: I17debc4d0efec3cebc203672333afb44390b0e0b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/115403 Reviewed-by: Martin Kustermann <[email protected]> Commit-Queue: Samir Jindel <[email protected]>
The issue you encountered should be fixed now. We need to do some additional investigation to ensure there are no similar issues. |
@sigalor Great, happy to hear that! 🎉 Do you have a version number of an upcoming release we will be able to verify with? |
The next dev release should contain it. You can see when it's released here: https://github.com/dart-lang/sdk/commits/dev |
@greenrobot If you are very eager to try it out now, you can download the bleeding-edge build, which should be available here gs://dart-archive/channels/be/raw/166289/sdk/dartsdk-linux-x64-release.zip |
It appears that there's not an issue with I'm not sure that the behavior should be different between OSes, but I can't find a way that it would break. |
OS: Ubuntu 20.04.2 LTS I'm having an issue where a To replicate call this function from Dart through ffi: void throwException()
{
try
{
throw std::runtime_error("Hello exception!");
}
catch (const std::exception &e)
{
auto cast_e = dynamic_cast<const std::runtime_error *>(&e);
// std::cout << e.what() << std::endl;
}
} The uncommented line also leads to a segmentation fault. This is not an issue on macOS. |
@blaugold The Dart C FFI interacts with C code. There is currently no C++ specific support. Throwing C++ exceptions across Dart frames is therefore not supported - and there are also no plans on supporting it in the near future. The FFI calls to C code expect that the C code returns normally (neither exceptions nor |
@mkustermann Thanks for the prompt reply. The issue I'm having surfaces in a C API that wraps a C++ API. This wrapper catches a C++ exception and turns it into an error code. The problem is that examining the exception to create the error code causes a crash. |
@blaugold Appologies, I misunderstood your problem. It's unclear to me to what extend the runtime system of Though when trying your example it seems to work for me:
@blaugold Could you provide the entire example? |
@mkustermann I have created a repo with the example. There is a file I've only tested the example on macOS and Linux and the issue only comes up on Linux. |
@mkustermann Your right. Using |
@blaugold Glad to hear! Just out of curiosity it works for me on Linux:
|
I noticed that I am using a different version of gcc (GNU 9.3.0).
|
@mkustermann FYI the Dart SDK included in the Flutter SDK still exposes symbols from the c++ abi. The example I provided now works for me, when I use the Dart SDK from https://dart.dev/get-dart. When using objdump -T ~/lib/flutter/stable/bin/cache/dart-sdk/bin/dart | grep __dynamic_cast
0000000001cc8f00 g DF .text 00000000000000f4 Base __dynamic_cast
~/lib/flutter/beta/bin/cache/dart-sdk/bin/dart --version
Dart SDK version: 2.12.0 (stable) (Thu Feb 25 19:50:53 2021 +0100) on "linux_x64" |
Operating System: Ubuntu 16.04
Dart version: 2.4.1
Used g++ version: 9.1.0
Related to #34452
To reproduce this issue, please create the following four files in the same directory and run
make
:Makefile
main.cpp
foo.cpp
main.dart
Expected behavior: Both
./main
anddart main.dart
outputHello exception!
.Actual behavior: Dart outputs
Missing exception info!
instead, becausestd::current_exception
returns a null pointer infoo.cpp
.Although the Dart FFI does not support handling exceptions itself (e.g. passing them back to Dart) right now, the underlying C++ code should be able to process them internally nonetheless. Currently, existing libraries which use
std::current_exception
might not work anymore or at least debugging becomes considerably harder.Namely, for debugging, the .so library needs to be compiled with debug information, so that e.g. with GDB one can set a breakpoint before the code that throws the exception, so its message can be inspected there. Of course, in a large code base, where the exact location of the executed
throw
statement is not known, this requires significantly more effort.The text was updated successfully, but these errors were encountered: