Repository navigation
run-make-fulldeps/foreign-exceptions loops on armv7-unknown-linux-gnueabihf #67242
Description
Activity
- addedA-testsuiteArea: The testsuite used to check the correctness of rustcArea: The testsuite used to check the correctness of rustcC-bugCategory: This is a bug.Category: This is a bug.O-ArmTarget: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 stateTarget: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 stateT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
on Dec 11, 2019 cc @rust-lang/wg-ffi-unwind
- addedA-FFIArea: Foreign function interface (FFI)Area: Foreign function interface (FFI)
on Dec 11, 2019 PS: while I initially saw this on Fedora rawhide, my followup testing has been on stable Fedora 31.
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
void foo() { throw 1234; }
b.cpp
void foo(); int main() { try { foo(); } catch (...) { printf("caught exception in catch (...)\n"); throw; } }
This should print the message once and then fail with an uncaught exception.
And this behavior only occurs on ARM?
Yes, the other arches completed and passed that test.
Can you try this C++-only code to see if it has the same issue?
Needs
#include <cstdio>forprintf, but then it works:$ g++ -c a.cpp $ g++ -c b.cpp $ g++ a.o b.o -o foo $ ./foo caught exception in catch (...) terminate called after throwing an instance of 'int' Aborted (core dumped)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(), 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...
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.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.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++?
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++ exceptionSo I commented out
throw_cxx_exceptionagain to just trythrow_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@cuviper you may need to explicitly link libcxxabi depending on how libcxx was built. That should fix undefined reference error.
@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.
I managed to reproduce this on Arch Linux with
qemu-arm, so it's definitely not a Fedora-only issue.Reacted by Josh Stone@cuviper no, that should be fine. Guess passing
--unwindlib=[libgcc|compiler-rt]to the Clang (supported since 9.0.0) doesn't help either?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".Reacted by Mateusz MikułaI'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.Ah nvmd, I just had to wrap the thing in single-quotes to reproduce the loop, the output of "pstree" is misleading.
Since this test is new in 1.40 I'll just
# ignore-armfor the time being in Debian.Should be fixed by #67779
- added a commit that references this issue
on Jan 2, 2020
When I tested 1.40.0-beta.5 on Fedora rawhide,
run-make-fulldeps/foreign-exceptionsnever completed onarmv7-unknown-linux-gnueabihf. When I run that test on arm directly, I get: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.
cc @Amanieu