Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/macos-26-expected.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
10 changes: 1 addition & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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).
Expand Down
56 changes: 32 additions & 24 deletions coregrind/m_sigframe/sigframe-arm64-darwin.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};


Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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,
Expand Down
1 change: 0 additions & 1 deletion drd/tests/sigaltstack.vgtest
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
prereq: ! ../../tests/os_test darwin
prog: ../../memcheck/tests/sigaltstack
vgopts: -q
9 changes: 9 additions & 0 deletions memcheck/tests/sigaltstack.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion memcheck/tests/sigaltstack.vgtest
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
prereq: ! ../../tests/os_test darwin
prog: sigaltstack
vgopts: -q
13 changes: 8 additions & 5 deletions none/tests/pth_term_signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down