Przeglądaj źródła

buildsys: give the socketcall and ipc multiplexers unwind tables

A cancellation point has to be unwindable: asynchronous cancellation
throws a forced unwind through the blocked frame, and if that frame has
no CFI record the unwinder cannot get out, so cleanup handlers never
run.  The wrappers are fine -- they are compiled as C -- but on the
architectures that still go through a multiplexer the thread is parked
inside __socketcall() or __syscall_ipc(), and those are _syscallN asm
macros with no unwind information at all.

That is what sparc-v8 shows once the nptl tests run:

  cleanup handler not called for 'accept'
  cleanup handler not called for 'send'
  cleanup handler not called for 'recv'
  cleanup handler not called for 'recvfrom'
  cleanup handler not called for 'recvmsg'
  cleanup handler not called for 'msgrcv'

while the other 30 cancellation points in tst-cancelx4 pass.  The same
class of bug was fixed for m68k accept() by 016a8c482 one call at a
time; this is the floor underneath it, and it covers every socketcall
architecture at once -- i386 built against pre-4.3 headers, m68k, ppc,
sh, s390 -- plus the ipc() multiplexer that msgrcv() blocks in.

Measured with the host objdump on the .os files, because cross-objdump
lies about .eh_frame:

  sparc  __socketcall.os    FDEs 0 -> 2, 1128 -> 1328 bytes
         __syscall_ipc.os   FDEs 0 -> 2
  m68k   __socketcall.os    FDEs 0 -> 1
         __syscall_ipc.os   FDEs 0 -> 1

The instruction sequence is byte for byte the same, 23 instructions
before and after -- the flag only emits .eh_frame, so this costs size
and nothing else.  x86 never noticed because gcc enables
-fasynchronous-unwind-tables there by default.

CFLAGS-raise.c and CFLAGS-abort.c already use the same mechanism for the
same reason.

Signed-off-by: Ramin Moussavi <lordrasmus@gmail.com>
ramin 1 tydzień temu
rodzic
commit
b5638b9f33

+ 3 - 0
libc/misc/sysvipc/Makefile.in

@@ -30,3 +30,6 @@ objclean-y += CLEAN_libc/misc/sysvipc
 
 
 CLEAN_libc/misc/sysvipc:
 CLEAN_libc/misc/sysvipc:
 	$(do_rm) $(addprefix $(MISC_SYSVIPC_OUT)/*., o os)
 	$(do_rm) $(addprefix $(MISC_SYSVIPC_OUT)/*., o os)
+
+# Same reason as CFLAGS-__socketcall.c: msgrcv() blocks in this multiplexer.
+CFLAGS-__syscall_ipc.c = -fasynchronous-unwind-tables

+ 3 - 0
libc/sysdeps/linux/common/Makefile.in

@@ -89,6 +89,9 @@ CSRC- += $(if $(findstring =arm=,=$(TARGET_ARCH)=),vfork.c)
 CSRC- += $(if $(findstring =x86_64=,=$(TARGET_ARCH)=),vfork.c)
 CSRC- += $(if $(findstring =x86_64=,=$(TARGET_ARCH)=),vfork.c)
 CSRC- += $(if $(findstring =metag=,=$(TARGET_ARCH)=),vfork.c)
 CSRC- += $(if $(findstring =metag=,=$(TARGET_ARCH)=),vfork.c)
 endif
 endif
+# Cancellation points block in this multiplexer and must be unwindable.
+CFLAGS-__socketcall.c = -fasynchronous-unwind-tables
+
 ifneq ($(ARCH_HAS_DEPRECATED_SYSCALLS),y)
 ifneq ($(ARCH_HAS_DEPRECATED_SYSCALLS),y)
 # No conversion is needed for new architectures
 # No conversion is needed for new architectures
 CSRC- += xstatconv.c
 CSRC- += xstatconv.c