The SIGSYS handler in sud_benchmark returns by hand: it loads
__NR_rt_sigreturn, runs leaveq to drop its frame, adjusts the stack and
issues the syscall. leaveq restores the stack from the frame pointer, so
the sequence only works in a function that has one.

gcc omits the frame pointer from -O1 up, so the handler restores a stack
that is not the signal frame and rt_sigreturn resumes at a bogus address:

  Caught sys_ff00
  Segmentation fault

The Makefile passes no -O, so a default build gets -O0 and works. A
distribution building the selftests with its own optimisation flags does
not: -O1 and -O2 both fault, and both pass again with
-fno-omit-frame-pointer.

Ask for the frame pointer, which is what the assembly needs. sud_test
does not use it and is unaffected.

Signed-off-by: Eva Kurchatova <[email protected]>
---
 tools/testing/selftests/syscall_user_dispatch/Makefile | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/testing/selftests/syscall_user_dispatch/Makefile 
b/tools/testing/selftests/syscall_user_dispatch/Makefile
index 03c120270953..249d9ed30c5c 100644
--- a/tools/testing/selftests/syscall_user_dispatch/Makefile
+++ b/tools/testing/selftests/syscall_user_dispatch/Makefile
@@ -3,7 +3,7 @@ top_srcdir = ../../../..
 INSTALL_HDR_PATH = $(top_srcdir)/usr
 LINUX_HDR_PATH = $(INSTALL_HDR_PATH)/include/
 
-CFLAGS += -Wall -I$(LINUX_HDR_PATH)
+CFLAGS += -Wall -fno-omit-frame-pointer -I$(LINUX_HDR_PATH)
 
 TEST_GEN_PROGS := sud_test sud_benchmark
 include ../lib.mk
-- 
2.55.0


Reply via email to