fix(build): avoid jt9 SIGSEGV from gfortran stack trampolines - #53
Open
cjkjellander wants to merge 1 commit into
Open
fix(build): avoid jt9 SIGSEGV from gfortran stack trampolines#53cjkjellander wants to merge 1 commit into
cjkjellander wants to merge 1 commit into
Conversation
gfortran compiles the FT8 decoder callback (an internal procedure passed as an actual argument) into a trampoline placed on the stack. Combined with the -Wa,--noexecstack hardening this crashes at run time (jt9 SIGSEGV in ft8_decode) on gfortran and hardened toolchains, because the trampoline cannot execute on a non-executable stack. Prefer heap-allocated trampolines when the compiler supports them (gfortran >= 14, -ftrampoline-impl=heap), which keeps the stack non-executable. On older compilers that lack the option, mark the stack executable so the trampoline runs instead of crashing.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On Linux,
jt9segfaults insideft8_decode(SIGSEGV) with gfortran andhardened toolchains. The FT8 decoder callback is an internal procedure passed
as an actual argument, which gfortran implements as a trampoline placed on
the stack. The
-Wa,--noexecstackhardening added for certain Linux buildsmarks the stack non-executable, so the trampoline can no longer run and the
process crashes as soon as a decode is produced.
This is a build-time-vs-run-time trade-off:
noexecstackkeeps strict linkershappy but breaks the decoder at run time; an executable stack runs but trips a
linker warning on hardened distros.
The clean resolution is to stop putting the trampoline on the stack at all.
gfortran 14 added
-ftrampoline-impl=heap, which allocates trampolines on theheap and lets the stack stay non-executable. This PR:
-ftrampoline-impl=heapwithcheck_fortran_compiler_flag;-Wa,--noexecstack(no crash, no warning, stack stays non-executable);
-Wa,--execstackso thetrampoline can run, rather than crashing.
The fallback re-introduces the non-fatal
ld: warning: ... requires executable stackon older compilers — that is the correct trade-off (a warning beats arun-time crash), and modern toolchains avoid both paths.
Verified on gfortran 13.3 (Ubuntu 24.04): without this,
jt9'sGNU_STACKisRWand it SIGSEGVs inft8_decode; with the fallback it isRWEand decodingworks. gfortran >= 14 selects the heap-trampoline path.