From: Paul Floyd Date: Sat, 25 Feb 2023 14:16:35 +0000 (+0100) Subject: FreeBSD: make rfork() fail more gracefully X-Git-Tag: VALGRIND_3_21_0~164 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b861458d3dcb8340a47c342ef161089594b18898;p=thirdparty%2Fvalgrind.git FreeBSD: make rfork() fail more gracefully rfork() is barely used in base FreeBSD. The main use is in posix_spawn(). If rfork() fails with EINVAL then it falls back to using vfork(). This is preferable to Valgrind bombing. ksh93 uses posix_spawn. I tested bash and csh and they had no problems. Also add 'hello world" smoke tests for bash csh and ksh --- diff --git a/NEWS b/NEWS index 7fcfc667a2..c6ebdcb252 100644 --- a/NEWS +++ b/NEWS @@ -95,6 +95,7 @@ are not entered into bugzilla tend to get forgotten about or ignored. 464859 Build failures with GCC-13 (drd tsan_unittest) 464969 D language demangling 465435 m_libcfile.c:66 (vgPlain_safe_fd): Assertion 'newfd >= VG_(fd_hard_limit)' failed. +n-i-bz FreeBSD rfork syscall fail with EINVAL or EINVAL rather than VG_(unimplemented) To see details of a given bug, visit https://bugs.kde.org/show_bug.cgi?id=XXXXXX diff --git a/coregrind/m_syswrap/syswrap-amd64-freebsd.c b/coregrind/m_syswrap/syswrap-amd64-freebsd.c index dfbca4d7b5..4372e6b719 100644 --- a/coregrind/m_syswrap/syswrap-amd64-freebsd.c +++ b/coregrind/m_syswrap/syswrap-amd64-freebsd.c @@ -305,12 +305,17 @@ PRE(sys_clock_getcpuclockid2) PRE(sys_rfork) { PRINT("sys_rfork ( %#" FMT_REGWORD "x )", ARG1 ); - PRE_REG_READ1(long, "rfork", int, flags); + PRE_REG_READ1(pid_t, "rfork", int, flags); - VG_(message)(Vg_UserMsg, "rfork() not implemented"); - VG_(unimplemented)("Valgrind does not support rfork()."); + VG_(message)(Vg_UserMsg, "warning: rfork() not implemented\n"); - SET_STATUS_Failure(VKI_ENOSYS); + if ((UInt)ARG1 == VKI_RFSPAWN) { + // posix_spawn uses RFSPAWN and it will fall back to vfork + // if it sees EINVAL + SET_STATUS_Failure(VKI_EINVAL); + } else { + SET_STATUS_Failure(VKI_ENOSYS); + } } // SYS_preadv 289 diff --git a/coregrind/m_syswrap/syswrap-x86-freebsd.c b/coregrind/m_syswrap/syswrap-x86-freebsd.c index e28183d943..e8e5a2f89d 100644 --- a/coregrind/m_syswrap/syswrap-x86-freebsd.c +++ b/coregrind/m_syswrap/syswrap-x86-freebsd.c @@ -740,9 +740,14 @@ PRE(sys_rfork) *flags |= SfYieldAfter; } #else - VG_(message)(Vg_UserMsg, "rfork() not implemented"); - VG_(unimplemented)("Valgrind does not support rfork() yet."); - SET_STATUS_Failure( VKI_ENOSYS ); + VG_(message)(Vg_UserMsg, "rfork() not implemented\n"); + if ((UInt)ARG1 == VKI_RFSPAWN) { + // posix_spawn uses RFSPAWN and it will fall back to vfork + // if it sees EINVAL + SET_STATUS_Failure(VKI_EINVAL); + } else { + SET_STATUS_Failure(VKI_ENOSYS); + } #endif } diff --git a/include/vki/vki-freebsd.h b/include/vki/vki-freebsd.h index 2bbaa44188..f9ca51c036 100644 --- a/include/vki/vki-freebsd.h +++ b/include/vki/vki-freebsd.h @@ -1608,6 +1608,9 @@ struct vki_dirent { #define VKI_W_OK 0x02 /* test for write permission */ #define VKI_R_OK 0x04 /* test for read permission */ +#define VKI_RFSPAWN (1U<<31U) + + //---------------------------------------------------------------------- // From sys/msg.h //---------------------------------------------------------------------- diff --git a/none/tests/freebsd/Makefile.am b/none/tests/freebsd/Makefile.am index f956078d68..8148245c79 100644 --- a/none/tests/freebsd/Makefile.am +++ b/none/tests/freebsd/Makefile.am @@ -37,7 +37,19 @@ EXTRA_DIST = \ usrstack.stderr.exp \ usrstack.stdout.exp \ proc_pid_file.vgtest \ - proc_pid_file.stderr.exp + proc_pid_file.stderr.exp \ + bash_test.vgtest \ + bash_test.sh \ + bash_test.stderr.exp \ + bash_test.stdout.exp \ + csh_test.vgtest \ + csh_test.csh \ + csh_test.stderr.exp \ + csh_test.stdout.exp \ + ksh_test.vgtest \ + ksh_test.ksh \ + ksh_test.stderr.exp \ + ksh_test.stdout.exp check_PROGRAMS = \ auxv osrel swapcontext hello_world fexecve 452275 usrstack \ diff --git a/none/tests/freebsd/bash_test.sh b/none/tests/freebsd/bash_test.sh new file mode 100755 index 0000000000..de85e3bc8d --- /dev/null +++ b/none/tests/freebsd/bash_test.sh @@ -0,0 +1,2 @@ +#!/usr/local/bin/bash +echo Bash Hello, World! diff --git a/none/tests/freebsd/bash_test.stderr.exp b/none/tests/freebsd/bash_test.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/freebsd/bash_test.stdout.exp b/none/tests/freebsd/bash_test.stdout.exp new file mode 100644 index 0000000000..1826a62d1d --- /dev/null +++ b/none/tests/freebsd/bash_test.stdout.exp @@ -0,0 +1 @@ +Bash Hello, World! diff --git a/none/tests/freebsd/bash_test.vgtest b/none/tests/freebsd/bash_test.vgtest new file mode 100644 index 0000000000..604cd133cb --- /dev/null +++ b/none/tests/freebsd/bash_test.vgtest @@ -0,0 +1,4 @@ +# bash isn't part of base +prereq: test -e /usr/local/bin/bash +prog: bash_test.sh +vgopts: -q diff --git a/none/tests/freebsd/csh_test.csh b/none/tests/freebsd/csh_test.csh new file mode 100755 index 0000000000..7e7b4a6bf2 --- /dev/null +++ b/none/tests/freebsd/csh_test.csh @@ -0,0 +1,2 @@ +#!/bin/csh +echo Csh Hello, World! diff --git a/none/tests/freebsd/csh_test.stderr.exp b/none/tests/freebsd/csh_test.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/freebsd/csh_test.stdout.exp b/none/tests/freebsd/csh_test.stdout.exp new file mode 100644 index 0000000000..f91c2ec681 --- /dev/null +++ b/none/tests/freebsd/csh_test.stdout.exp @@ -0,0 +1 @@ +Csh Hello, World! diff --git a/none/tests/freebsd/csh_test.vgtest b/none/tests/freebsd/csh_test.vgtest new file mode 100644 index 0000000000..eaa5460ac1 --- /dev/null +++ b/none/tests/freebsd/csh_test.vgtest @@ -0,0 +1,2 @@ +prog: csh_test.csh +vgopts: -q diff --git a/none/tests/freebsd/ksh_test.ksh b/none/tests/freebsd/ksh_test.ksh new file mode 100755 index 0000000000..8dc470d990 --- /dev/null +++ b/none/tests/freebsd/ksh_test.ksh @@ -0,0 +1,2 @@ +#!/usr/local/bin/ksh93 +print Ksh Hello, World! diff --git a/none/tests/freebsd/ksh_test.stderr.exp b/none/tests/freebsd/ksh_test.stderr.exp new file mode 100644 index 0000000000..e69de29bb2 diff --git a/none/tests/freebsd/ksh_test.stdout.exp b/none/tests/freebsd/ksh_test.stdout.exp new file mode 100644 index 0000000000..ebd37bca8b --- /dev/null +++ b/none/tests/freebsd/ksh_test.stdout.exp @@ -0,0 +1 @@ +Ksh Hello, World! diff --git a/none/tests/freebsd/ksh_test.vgtest b/none/tests/freebsd/ksh_test.vgtest new file mode 100644 index 0000000000..af99583f54 --- /dev/null +++ b/none/tests/freebsd/ksh_test.vgtest @@ -0,0 +1,4 @@ +# ksh isn't part of base +prereq: test -e /usr/local/bin/ksh93 +prog: ksh_test.ksh +vgopts: -q