-
Notifications
You must be signed in to change notification settings - Fork 18k
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
cmd/compile: SIGILL on ARMv7 after a C++ throw #20089
Comments
Could you try to disable thumb? Apparently the instruction in semrelease is valid, but it can be invalid in thumb mode. Go doesn't use thumb mode. It seems when it throws in thumb mode, it doesn't switch to arm mode. |
@cherrymui I tried compiling our c/c++ code using Is it possible to disable -marm in golang and just go with thumb? FWIW, I also tried compiling with |
Could you post the new stack trace on failure? The stack trace in the earlier post shows that it goes into thumb mode very early:
(because the PC is not 4-byte aligned)
I suspect libc supports both arm and thumb, and the linker should choose the right one. Could you paste your build process with
No. Go assembler doesn't know thumb at all. For this to work it would require adding an entire backend. |
I compiled all our c/c++ packages with
and here's a new back trace (looks 4 byte aligned):
still happening:
and here's the instruction:
|
@bassam Thank you for the new stack trace. The PCs look like indeed 4-byte aligned. To make sure it is in arm mode, could you print the instruction and $cpsr in gdb when it throws? If it looks like in thumb mode, could you print the instructions for the call sites on each frame, to see when it switches to thumb? In your code, whom do you expect to handle the throw? C++, Go, or nothing (terminate program)? I don't know why/how it goes to runtime.semrelease. If it is in thumb mode, it could just jump wildly though. The build log looks like a -v log from the linker, instead of Is there a way I could build your code and reproduce it? Thank you. |
@cherrymui, here's the instruction and cpsr at the throw:
also here are the instructions at each call site:
I expect the C++ code to handle the throw. |
Also here's the go build -x output:
If you want to build it yourself here's the branch I'm using https://github.com/bassam/rook/tree/pr-armhf. Build instructions are here https://github.com/bassam/rook/tree/pr-armhf/build, I'm running the following to build for arm:
I'm also happy to arrange an ssh session if you'd like to debug live. Thanks for all your help! |
@bassam From the CPSR it looks like it is in thumb mode. Unfortunately the PCs for each frame you pasted are the instruction after the call instruction. What I'd like to find out is whether it switches to thumb at one of calls (BLX instruction). If you print the previous instruction (or simply do It is interesting that C++ doesn't handle the throw and it jumps to Go code. Probably messed up with arm/thumb mode... Do you have a standalone C++ binary that exercises the same code path? Maybe just call the function that you called with Cgo directly from C++ with the same arguments? If so, could you try to build it with -marm to see whether the throw is handled properly? Thank you for the build instruction. I'll give it a try. |
@cherrymui here are the binaries if you want to take a look:
The first link has the |
@bassam Sorry for the delayed. I looked at your binary. It seems it goes to thumb mode at If you have both ARM and thumb ones, it is useful to know how the linker is invoked. Do you use the Go linker or the C++ linker to produce the final binary? What flags are used? Thanks. |
@cherrymui thanks that makes a lot of sense! I'll check the version of libstdc++ and hopefully that fixes the issue. I learned a lot about golang and ARM from this issue. Thanks again. |
Please answer these questions before submitting your issue. Thanks!
What version of Go are you using (
go version
)?go 1.8.1
What operating system and processor architecture are you using (
go env
)?What did you do?
I cross compiled Rook for armhf (see rook/rook#497) but it seems to fail with a SIGILL on an Armv7 (Scaleway C1 machines). Everything works fine for aarch64 and amd64 but not arm.
Leading up to the SIGILL I see a SIGSEGV
when I continue I see the following:
Here's the cpu info:
Note that I'm cross compiling rook with arm-linux-gnueabihf-gcc, here's the version info:
Note the
--with-arch=armv7-a --with-fpu=vfpv3-d16 --with-float=hard --with-mode=thumb
defaults.Also note that
rookd
is a statically compiled binary and libc/libc++ are also statically compiled in.What did you expect to see?
No SIGILL
The text was updated successfully, but these errors were encountered: