You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
run-make-fulldeps/foreign-exceptions loops on armv7-unknown-linux-gnueabihf #67242
When I tested 1.40.0-beta.5 on Fedora rawhide, run-make-fulldeps/foreign-exceptions never completed on armv7-unknown-linux-gnueabihf. When I run that test on arm directly, I get:
throwing C++ exception
DropCheck::drop
caught C++ exception
throwing rust panic
thread 'main' panicked at 'Box<Any>', foo.rs:42:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
caught foreign exception in catch (...)
caught foreign exception in catch (...)
caught foreign exception in catch (...)
caught foreign exception in catch (...)
caught foreign exception in catch (...)
caught foreign exception in catch (...)
[... and so on ...]
The same happens when I use official builds of Rust 1.40-beta and 1.41-nightly, so it's not just a problem with Fedora's build of rustc or LLVM. This test didn't exist before #65646, but running 1.39 on the current test just fails even earlier, as expected, "entered unreachable code: catch_unwind should not have caught foreign exception."
I tried compiling the C++ part with GCC 9.2.1 and Clang 9.0.0, both with the same result. That's using libstdc++ either way though, because we don't have LLVM's libc++ available.
This test didn't exist before #65646, but running 1.39 on the current test just fails even earlier, as expected, "entered unreachable code: catch_unwind should not have caught foreign exception."
I tried stable 1.39 again commenting out the call to throw_cxx_exception(), then throw_rust_panic() gets stuck in the same "caught foreign exception in catch" loop on the C++ side. In fact, this happens on every compiler I tried back to 1.13, which is the earliest I could get working at all!
So at least it's not a new problem. Maybe we're generating bad unwind data, or maybe my libgcc has a bug in handling foreign exceptions, I don't know...
Oh, I found that Fedora does have libc++ packaged, libcxx-devel and libcxxabi-devel. But when I tried to use it simply as you indicate, foreign exceptions don't seem to be caught at all, in either direction. I see the binary still gets gcc_s linked implicitly though, I think because libunwind/build.rs adds it to std. I'll try to get a full build of rustc with just libc++ instead.
Maybe this is obvious, but I have to compile the C++ part with clang++, not g++, or it gets "undefined reference to __cxa_end_cleanup". I wasn't sure whether to also use -stdlib=libc++, but either way the C++ exception is not caught by Rust:
terminating with uncaught exception of type exception
throwing C++ exception
So I commented out throw_cxx_exception again to just try throw_rust_panic:
throwing rust panic
thread 'main' panicked at 'Box<Any>', foo.rs:42:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
fatal runtime error: failed to initiate panic, error 9
@mati865 I did use -lc++ -lc++abi -- do you mean more than that?
If anyone else is interested in arm-linux, it would be great to get more hands on this, because that target is not a high priority for me. I will probably disable this test for arm in Fedora in the meantime.
The link error was only when using g++ to compile foo.cpp. That much was ok with clang++. I just tried adding --unwindlib to the clang command too, but got "argument unused during compilation".
I'm hitting this on Debian too. Running foo by itself does result in infinite-loop printing caught foreign exception in catch (...) however the rust test suite is actually running /bin/sh -c LD_LIBRARY_PATH="/home/infinity0/rustc/build/armv5te-unknown-linux-gnueabi/test/run-make-fulldeps/foreign-exceptions/foreign-exceptions:/home/infinity0/rustc/build/armv5te-unknown-linux-gnueabi/stage2/lib/rustlib/armv5te-unknown-linux-gnueabi/lib:/home/infinity0/rustc/build/armv5te-unknown-linux-gnueabi/stage0-bootstrap-tools/armv5te-unknown-linux-gnueabi/release/deps:/usr/lib" /home/infinity0/rustc/build/armv5te-unknown-linux-gnueabi/test/run-make-fulldeps/foreign-exceptions/foreign-exceptions/foo. Directly running this however exits immediately, so I don't know why the test is hanging. I'll see if I can grab the environment from /proc/$pid/env next time.
Activity
Mark-Simulacrum commentedon Dec 11, 2019
cc @rust-lang/wg-ffi-unwind
cuviper commentedon Dec 11, 2019
PS: while I initially saw this on Fedora rawhide, my followup testing has been on stable Fedora 31.
Amanieu commentedon Dec 11, 2019
That is very strange. And this behavior only occurs on ARM?
I'm tempted to say that this is a bug in GCC's unwinder (in libgcc). Can you try this C++-only code to see if it has the same issue?
a.cpp
b.cpp
This should print the message once and then fail with an uncaught exception.
cuviper commentedon Dec 11, 2019
Yes, the other arches completed and passed that test.
Needs
#include <cstdio>forprintf, but then it works:cuviper commentedon Dec 12, 2019
I tried stable 1.39 again commenting out the call to
throw_cxx_exception(), thenthrow_rust_panic()gets stuck in the same "caught foreign exception in catch" loop on the C++ side. In fact, this happens on every compiler I tried back to 1.13, which is the earliest I could get working at all!So at least it's not a new problem. Maybe we're generating bad unwind data, or maybe my libgcc has a bug in handling foreign exceptions, I don't know...
Amanieu commentedon Dec 12, 2019
I think this might be a bug in the way the personality routine in libstdc++ (libsupc++ actually) handles foreign exceptions on ARM.
Can you try using libc++ instead of libstdc++? Just change the linker args for rustc from
-lstdc++ -lgcc_sto-lc++ -lc++abi.cuviper commentedon Dec 12, 2019
Oh, I found that Fedora does have libc++ packaged,
libcxx-develandlibcxxabi-devel. But when I tried to use it simply as you indicate, foreign exceptions don't seem to be caught at all, in either direction. I see the binary still getsgcc_slinked implicitly though, I think because libunwind/build.rs adds it to std. I'll try to get a full build of rustc with just libc++ instead.Amanieu commentedon Dec 12, 2019
It's fine to link to
gcc_s, since that contains the libunwind implementation. The actual C++ personality functions are in libstd++/libc++abi.Can you post the test output with libc++?
cuviper commentedon Dec 12, 2019
Maybe this is obvious, but I have to compile the C++ part with clang++, not g++, or it gets "undefined reference to
__cxa_end_cleanup". I wasn't sure whether to also use-stdlib=libc++, but either way the C++ exception is not caught by Rust:So I commented out
throw_cxx_exceptionagain to just trythrow_rust_panic:mati865 commentedon Dec 12, 2019
@cuviper you may need to explicitly link libcxxabi depending on how libcxx was built. That should fix undefined reference error.
cuviper commentedon Dec 12, 2019
@mati865 I did use
-lc++ -lc++abi-- do you mean more than that?If anyone else is interested in arm-linux, it would be great to get more hands on this, because that target is not a high priority for me. I will probably disable this test for arm in Fedora in the meantime.
Amanieu commentedon Dec 12, 2019
I managed to reproduce this on Arch Linux with
qemu-arm, so it's definitely not a Fedora-only issue.mati865 commentedon Dec 12, 2019
@cuviper no, that should be fine. Guess passing
--unwindlib=[libgcc|compiler-rt]to the Clang (supported since 9.0.0) doesn't help either?cuviper commentedon Dec 12, 2019
The link error was only when using g++ to compile foo.cpp. That much was ok with clang++. I just tried adding
--unwindlibto the clang command too, but got "argument unused during compilation".infinity0 commentedon Dec 29, 2019
I'm hitting this on Debian too. Running
fooby itself does result in infinite-loop printingcaught foreign exception in catch (...)however the rust test suite is actually running/bin/sh -c LD_LIBRARY_PATH="/home/infinity0/rustc/build/armv5te-unknown-linux-gnueabi/test/run-make-fulldeps/foreign-exceptions/foreign-exceptions:/home/infinity0/rustc/build/armv5te-unknown-linux-gnueabi/stage2/lib/rustlib/armv5te-unknown-linux-gnueabi/lib:/home/infinity0/rustc/build/armv5te-unknown-linux-gnueabi/stage0-bootstrap-tools/armv5te-unknown-linux-gnueabi/release/deps:/usr/lib" /home/infinity0/rustc/build/armv5te-unknown-linux-gnueabi/test/run-make-fulldeps/foreign-exceptions/foreign-exceptions/foo. Directly running this however exits immediately, so I don't know why the test is hanging. I'll see if I can grab the environment from/proc/$pid/envnext time.infinity0 commentedon Dec 29, 2019
Ah nvmd, I just had to wrap the thing in single-quotes to reproduce the loop, the output of "pstree" is misleading.
infinity0 commentedon Dec 29, 2019
Since this test is new in 1.40 I'll just
# ignore-armfor the time being in Debian.Amanieu commentedon Jan 1, 2020
Should be fixed by #67779
Auto merge of #67779 - Amanieu:ehabi_fix, r=Mark-Simulacrum