diff --git a/.github/macos-26-expected.txt b/.github/macos-26-expected.txt index 50b9665ff..b9c1a8dc9 100644 --- a/.github/macos-26-expected.txt +++ b/.github/macos-26-expected.txt @@ -175,6 +175,7 @@ memcheck/tests/sendmsg (stderr) memcheck/tests/sh-mem-random (stdout) memcheck/tests/sh-mem-random (stderr) memcheck/tests/sh-mem (stderr) +memcheck/tests/sigaltstack (stderr) memcheck/tests/sigkill (stderr) memcheck/tests/signal2 (stderr) memcheck/tests/sigprocmask (stderr) diff --git a/README.md b/README.md index e56f19b00..cfe3138ac 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,10 @@ This repository contains a version of Valgrind including a few patches to improv | macOS 15 (Sequoia) | - | ✅ | ~[^2] | - | | macOS 26 (Tahoe) | - | ✅ | ✅ | - | -[^1]: Supported as part of upstream Valgrind. +[^1]: Supported as part of upstream Valgrind [^2]: macOS 15 arm64 is experimental ([#123](https://github.com/LouisBrunner/valgrind-macos/issues/123)) [^3]: PowerPC is unsupported ([#62](https://github.com/LouisBrunner/valgrind-macos/issues/62)) -Note that every version from macOS 10.12 onwards currently has the following issues: - -- using threads and signals together is undefined (crashes, hanging, etc), note: a few tests were disabled because of that - ## Usage In case you already have Valgrind installed, you might need to `brew remove` it first. @@ -65,10 +61,6 @@ brew upgrade --fetch-HEAD LouisBrunner/valgrind/valgrind ## Tests -Some tests are hanging and were therefore disabled on macOS: - -- `memcheck/tests/sigaltstack` & `drd/tests/sigaltstack` (arm64) - ### Linux (Ubuntu 24.04) These errors seem to come from the CI environment itself (as they show with or without my changes). diff --git a/coregrind/m_sigframe/sigframe-arm64-darwin.c b/coregrind/m_sigframe/sigframe-arm64-darwin.c index 3cac58fd7..37332cbc9 100644 --- a/coregrind/m_sigframe/sigframe-arm64-darwin.c +++ b/coregrind/m_sigframe/sigframe-arm64-darwin.c @@ -56,18 +56,21 @@ be important for Darwin. (be conservative) */ +const UInt MAGIC_PI = 0x31415927U; + +struct vg_sigframe { + UInt magicPI; + UInt sigNo_private; + vki_sigset_t mask; + VexGuestARM64State vex; + VexGuestARM64State vex_shadow1; + VexGuestARM64State vex_shadow2; +}; + struct hacky_sigframe { vki_siginfo_t info; struct vki_ucontext uc; - - unsigned long retcode[2]; - - UInt magicPI; - UInt sigNo_private; - vki_sigset_t mask; - VexGuestARM64State vex; - VexGuestARM64State vex_shadow1; - VexGuestARM64State vex_shadow2; + struct vg_sigframe vg; }; @@ -150,16 +153,21 @@ void VG_(sigframe_create)( ThreadId tid, if (! ML_(sf_maybe_extend_stack)(tst, sp, size, flags)) return; // Give up. No idea if this is correct - frame = (struct hacky_sigframe *) sp; + frame = (struct hacky_sigframe *) sp; + + VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler internal frame", + (Addr)frame, offsetof(struct hacky_sigframe, vg)); /* save stuff in frame */ - // FIXME: track writes? - frame->magicPI = 0x31415927; - frame->sigNo_private = siginfo->si_signo; - frame->mask = tst->sig_mask; - frame->vex = tst->arch.vex; - frame->vex_shadow1 = tst->arch.vex_shadow1; - frame->vex_shadow2 = tst->arch.vex_shadow2; + frame->vg.magicPI = MAGIC_PI; + frame->vg.sigNo_private = siginfo->si_signo; + frame->vg.mask = tst->sig_mask; + frame->vg.vex = tst->arch.vex; + frame->vg.vex_shadow1 = tst->arch.vex_shadow1; + frame->vg.vex_shadow2 = tst->arch.vex_shadow2; + + VG_TRACK( post_mem_write, Vg_CoreSignal, tst->tid, + (Addr)frame, offsetof(struct hacky_sigframe, vg)); /* Fill in the siginfo and ucontext. */ VG_TRACK( pre_mem_write, Vg_CoreSignal, tst->tid, "signal handler frame", @@ -237,19 +245,19 @@ void VG_(sigframe_destroy)( ThreadId tid, Bool isRT ) sp = VG_(get_SP)(tid); frame = (struct hacky_sigframe *)sp; - vg_assert(frame->magicPI == 0x31415927); + vg_assert(frame->vg.magicPI == MAGIC_PI); vg_assert(VG_IS_16_ALIGNED((Addr)frame)); /* restore the entire guest state, and shadows, from the frame. */ - tst->arch.vex = frame->vex; - tst->arch.vex_shadow1 = frame->vex_shadow1; - tst->arch.vex_shadow2 = frame->vex_shadow2; + tst->arch.vex = frame->vg.vex; + tst->arch.vex_shadow1 = frame->vg.vex_shadow1; + tst->arch.vex_shadow2 = frame->vg.vex_shadow2; restore_from_ucontext(tst, &frame->uc); - tst->sig_mask = frame->mask; - tst->tmp_sig_mask = frame->mask; - sigNo = frame->sigNo_private; + tst->sig_mask = frame->vg.mask; + tst->tmp_sig_mask = frame->vg.mask; + sigNo = frame->vg.sigNo_private; if (VG_(clo_trace_signals)) VG_(message)(Vg_DebugMsg, diff --git a/drd/tests/sigaltstack.vgtest b/drd/tests/sigaltstack.vgtest index a757cfe57..a079d603c 100644 --- a/drd/tests/sigaltstack.vgtest +++ b/drd/tests/sigaltstack.vgtest @@ -1,3 +1,2 @@ -prereq: ! ../../tests/os_test darwin prog: ../../memcheck/tests/sigaltstack vgopts: -q diff --git a/memcheck/tests/sigaltstack.c b/memcheck/tests/sigaltstack.c index 2892ebbe9..4657f1005 100644 --- a/memcheck/tests/sigaltstack.c +++ b/memcheck/tests/sigaltstack.c @@ -18,8 +18,17 @@ int main(int argv, char** argc) { // We give EXEC permissions because this won't work on ppc32 unless you // ask for an alt stack with EXEC permissions, // since signal returning requires execution of code on the stack. +#if defined(VGO_darwin) + char *stk = (char *)mmap(0, size, PROT_READ|PROT_WRITE, + MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + if (stk == MAP_FAILED) { + perror("mmap"); + return 1; + } +#else char *stk = (char *)mmap(0, size, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); +#endif sigstk.ss_sp = stk; sigstk.ss_size = size; diff --git a/memcheck/tests/sigaltstack.vgtest b/memcheck/tests/sigaltstack.vgtest index 44c12d28c..3d2b20bed 100644 --- a/memcheck/tests/sigaltstack.vgtest +++ b/memcheck/tests/sigaltstack.vgtest @@ -1,3 +1,2 @@ -prereq: ! ../../tests/os_test darwin prog: sigaltstack vgopts: -q diff --git a/none/tests/pth_term_signal.c b/none/tests/pth_term_signal.c index 15242704f..b873778c6 100644 --- a/none/tests/pth_term_signal.c +++ b/none/tests/pth_term_signal.c @@ -69,12 +69,15 @@ int main(int argc, char **argv) if ( ! childpid) childprocess(); - sleep(1); - - if (kill(childpid, SIGTERM)) + // Required on macOS (10.12+) due to timing issues + for (int i = 0; i < 5; ++i) { - fprintf(stderr, "Error line %u\n", __LINE__); - return 255; + if (kill(childpid, SIGTERM)) + { + fprintf(stderr, "Error line %u\n", __LINE__); + return 255; + } + sleep(1); } int status;