Skip to content

propagate canonical exit status through exit_group and epoch_kill#1169

Merged
rennergade merged 8 commits intomainfrom
exit-status-propagation
May 8, 2026
Merged

propagate canonical exit status through exit_group and epoch_kill#1169
rennergade merged 8 commits intomainfrom
exit-status-propagation

Conversation

@qianxichen233
Copy link
Copy Markdown
Contributor

Problem

When a process exited with a non-zero code (e.g. faulthandler calling
_exit(1)), the parent's waitpid() could observe exit code 0 instead.
This is the root reason of python test worker bug observed in python tests.
This was caused by three separate but related issues:

1. exit_syscall recorded the cage exit status

exit_syscall (SYS_exit = 60) is called by glibc's start_thread when a
non-main pthread returns from its thread function. It was calling
cage_record_exit_status(0) even though a per-thread exit has no bearing on
the process-level exit code. cage_record_exit_status uses first-write-wins
semantics, so if SYS_exit(0) fired before exit_group_syscall(1), it locked
final_exit_status = Some(0) and the subsequent exit_group(1) could not
overwrite it. cage_finalize then reported exit code 0 to the parent.

The glibc thread exit sequence is:

atomic_store_release(&pd->tid, 0)  // marks thread done, unblocks pthread_join
FUTEX_WAKE(&pd->tid, 1)            // wakes joiner
EXIT_SYSCALL(0)                    // very next instruction

pthread_join returns right after FUTEX_WAKE, so the joiner's return path
(asyncify rewind + multiple library frames) loses the race to thread A's
cage_record_exit_status(0), which fires at the top of exit_syscall before
any asyncify unwind.

2. exit_group_syscall passed its own status_arg to the exit trampoline

Late threads calling exit_group_syscall(0) after the cage was already marked
Exited(1) passed status_arg = 0 to the wasmtime exit trampoline. The last
thread's exit code determines the value returned to OnCalledAction::Finish,
so a late exit_group(0) could overwrite the intended code.

3. signal_handler hardcoded exit code 0 for epoch-killed threads

When exit_group or a fatal signal called epoch_kill_all, epoch-killed
threads entered signal_handler and called ctx.exit_call(caller, 0, 0).
This hardcoded 0 was passed to OnCalledAction::Finish regardless of what
exit code had been recorded.

Fix

  • exit_syscall: remove the cage_record_exit_status call entirely. Only
    exit_group_syscall determines the process-level exit code.

  • exit_group_syscall: compute canonical_status_arg by reading
    cage.final_exit_status at the point of calling the exit trampoline.
    Late threads calling exit_group(0) after the CAS winner recorded Exited(1)
    will use the authoritative code.

  • signal_handler (epoch_kill path): read cage.final_exit_status and
    pass the recorded exit code to ctx.exit_call instead of hardcoding 0.

Test

tests/unit-tests/process_tests/deterministic/exit_status_first_wins.c

Forks a child that creates a pthread which returns NULL (triggering
SYS_exit(0) via glibc start_thread), then calls exit(1) after
pthread_join. Because pthread_join returns before EXIT_SYSCALL fires,
thread A's cage_record_exit_status(0) races with the main thread's
exit_group(1). Thread A wins the race on the unfixed branch (asyncify rewind
overhead delays the main thread). Parent must observe exit code 1.

Three related fixes:
- exit_syscall: do not record per-thread exit status; only exit_group
  determines the cage's process-level exit code
- exit_group_syscall: use the cage's already-recorded final_exit_status
  so whichever thread wins the CAS (e.g. faulthandler calling _exit(1))
  determines the OS-level exit code; late threads calling exit_group(0)
  will use the authoritative code
- signal_handler (epoch_kill path): read the cage's final_exit_status
  instead of hard-coding 0 so the wasmtime exit trampoline receives the
  correct exit code
Tests that when two threads race to call exit(), the first caller's
exit code is what the parent sees via waitpid(). Worker thread calls
exit(1) and the main thread calls exit(0) after a spin; parent should
observe exit code 1.
The bug was that exit_syscall (SYS_exit, called by glibc start_thread
when a non-main pthread returns) called cage_record_exit_status(0).
cage_record_exit_status uses first-write-wins semantics, so if
SYS_exit(0) fires before exit_group(1), final_exit_status is locked
at 0 and cage_finalize reports 0 to the parent.

The new test creates a thread that returns NULL, then after
pthread_join calls exit(1). glibc's thread exit order is
FUTEX_WAKE → EXIT_SYSCALL(0), so pthread_join returns just before
EXIT_SYSCALL. Thread A's cage_record_exit_status(0) fires before
main's asyncify-rewind path reaches exit(1), locking status=0 on
the unfixed branch. After the fix, exit_syscall does not record
status, so exit_group(1) writes Some(1) first.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

End-to-End Test Report

Test Preview

grate harness

Grate Test Report

MetricValue
Total14
Success14
Failures0
Compile Failures0
Runtime Failures0
Timeout Failures0
Missing Pair Failures0

Cases

TestStatusError TypeOutput
concurrent-request/geteuid_grate.cSuccess
STDOUT:
[Grate|geteuid] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 3
[Cage | geteuid] PASS: 1000000 calls returned 10
[Grate|geteuid] PASS

STDERR:

concurrent-request/race-test_grate.cSuccess
STDOUT:
pass

STDERR:

concurrent-request/thread_race_grate.cSuccess
STDOUT:
[thread_race] Registering handler for cage 2 in grate 1 with fn ptr addr: 3
[thread_race] PASS: 20 threads x 100000 calls returned 10
[thread_race] PASS

STDERR:

copy-data-between-cages/cp-stncpy_grate.cSuccess
STDOUT:
[cage] pathname addr=0xfffb6ff9
[cage] pathname='random'
[Grate|open] intercepts open call: thiscage=1, arg1cage=2
[Grate|open] copied pathname: random
[cage] fd=10

STDERR:

copy-data-between-cages/cpdata_grate.cSuccess
STDOUT:
[Grate|open] intercepts open call: thiscage=1, arg1cage=2
[Grate|open] copied pathname: random
[cage] fd=10

STDERR:

interposing-calls/fork-with-newret_grate.cSuccess
STDOUT:
[Grate|interpose-fork] Registering fork handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|interpose-fork] Handling function ptr: 3 from cage: 1
[Grate|interpose-fork] In fork_grate 1 handler for cage: 1
[Cage] Forked process with PID: 10
[Grate|interpose-fork] PASS

STDERR:

interposing-calls/interpose-exec_grate.cSuccess
STDOUT:
[Grate|interpose-exec] Registering exec handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|interpose-exec] Handling function ptr: 3 from cage: 1
[Grate|interpose-exec] In exec_grate 1 handler for cage: 1
[Grate|interpose-exec] Handling function ptr: 3 from cage: 1
[Grate|interpose-exec] In exec_grate 1 handler for cage: 1
Exec successful, argv[1]: --execd
[Grate|interpose-exec] PASS

STDERR:

interposing-calls/interpose-exit_grate.cSuccess
STDOUT:
[Grate|interpose-exit] Registering exit handler for cage 2 in grate 1 with fn ptr addr: 3
Exiting...

[Grate|interpose-exit] PASS

STDERR:

interposing-calls/interpose-fork_grate.cSuccess
STDOUT:
[Grate|interpose-fork] Registering fork handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|interpose-fork] Handling function ptr: 3 from cage: 1
[Grate|interpose-fork] In fork_grate 1 handler for cage: 1
[Grate|interpose-fork] PASS

STDERR:

interposing-calls/interpose-mmap_grate.cSuccess
STDOUT:
[Grate|interpose-mmap] Registering mmap handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
mmap test: PASS
[Grate|interpose-mmap] PASS

STDERR:

interposing-calls/interpose-register_grate.cSuccess
STDOUT:
[Grate|interpose-register] Registering register_handler for cage 2 in grate 1 with fn ptr addr: 4
[cage] registering 107. grateid: 2 cageid: 3
[Grate|interpose-register] Handling function ptr: 4 from cage: 1
[Grate|interpose-register] In register_grate 1 handler for cage: 1
[Grate|geteuid] Registering geteuid handler for cage 1 in grate 1 with fn ptr addr: 3
[Grate|interpose-register] Handling function ptr: 3 from cage: 1
[Grate|interpose-register] In register_grate 1 handler for cage: 1
[Grate|interpose-register] PASS

STDERR:

multi-register_grate.cSuccess
STDOUT:
[Grate|multi-register_grate] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 4
[Grate|multi-register_grate] Registering getuid handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|multi-register_grate] Handling function ptr: 4 from cage: 1
[Grate|multi-register_grate] In multi-register_grate 1 handler for cage: 1
[Grate|multi-register_grate] Handling function ptr: 3 from cage: 1
[Grate|multi-register_grate] In multi-register_grate 1 handler for cage: 1
[Cage | multi-register] PASS: geteuid=10, getuid=20
[Grate|multi-register] PASS

STDERR:

simple-tests/diff-cage-args_grate.cSuccess
STDOUT:
[Grate|diff-cage-args] Handling function ptr: 3 from cage: 1
[Grate|diff-cage-args] In open_grate 1 handler for cage: 1
Hello world. FD=-1
[Grate|diff-cage-args] Handling function ptr: 4 from cage: 1
Goodbye world! ret=4321 buf=helloworld
[Grate|diff-cage-args] PASS

STDERR:

simple-tests/geteuid_grate.cSuccess
STDOUT:
[Grate|geteuid] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|geteuid] Handling function ptr: 3 from cage: 1
[Grate|geteuid] In geteuid_grate 1 handler for cage: 1
[Cage | geteuid] PASS: geteuid ret = 10
[Grate|geteuid] PASS

STDERR:

static harness

Test Report

Deterministic Tests

Summary

MetricCount
Total Test Cases3
Number of Successes3
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

Test Results by Category

Test CaseStatusError TypeNative TimeWasm TimeOutput
Static Tests
fork_simple.cSuccessNone0.058105s4.452732s
Success
thread.cSuccessNone0.051792s4.506949s
Success
tls_test.cSuccessNone0.062706s4.536852s
Success
Fail Tests

Summary

MetricCount
Total Test Cases0
Number of Successes0
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

wasm harness

Test Report

Deterministic Tests

Summary

MetricCount
Total Test Cases214
Number of Successes213
Number of Failures1
Number of Compilation Failure Native1
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

Test Results by Category

Test CaseStatusError TypeNative TimeWasm TimeOutput
File Tests
chartests.cSuccessNone0.051603s0.145584s
Success
chdir_getcwd.cSuccessNone0.053685s0.116247s
Success
chmod.cSuccessNone0.057261s0.125081s
Success
clock_gettime_highlevel.cSuccessNone0.124750s0.170859s
Success
clock_gettime_simple.cSuccessNone0.048619s0.109580s
Success
cloexec.cSuccessNone0.056939s0.133756s
Success
close.cSuccessNone0.066910s0.140025s
Success
creat_access.cSuccessNone0.056889s0.118290s
Success
doubleclose.cSuccessNone0.047857s0.100442s
Success
dup.cSuccessNone0.049039s0.115684s
Success
dup2.cSuccessNone0.053589s0.114579s
Success
dup3.cSuccessNone0.052099s0.118232s
Success
dupwrite.cSuccessNone0.055170s0.113823s
Success
etc_conf.cSuccessNone0.051655s0.120125s
Success
fchdir.cSuccessNone0.056744s0.128042s
Success
fchmod.cSuccessNone0.056164s0.127201s
Success
fcntl.cSuccessNone0.053991s0.130761s
Success
fdatasync.cSuccessNone0.055875s0.112801s
Success
filetest.cSuccessNone0.055405s0.112946s
Success
filetest1000.cSuccessNone0.064981s0.125695s
Success
flock.cSuccessNone0.062938s0.151177s
Success
fstat.cSuccessNone0.057126s0.128794s
Success
fstatfs.cSuccessNone0.050500s0.109161s
Success
fsync.cSuccessNone0.056656s0.115351s
Success
ftruncate.cSuccessNone0.059509s0.214646s
Success
getcwd.cSuccessNone0.051193s0.106244s
Success
getcwd_null.cSuccessNone0.055081s0.119778s
Success
getpgid.cSuccessNone0.049588s0.103887s
Success
getrandom.cSuccessNone0.054823s0.126617s
Success
ioctl.cSuccessNone0.056424s0.122328s
Success
link.cSuccessNone0.058742s0.158095s
Success
locale_test.cSuccessNone0.066590s0.321744s
Success
lseek.cSuccessNone0.058648s0.190795s
Success
lstat.cSuccessNone0.058548s0.137524s
Success
mkdir_rmdir.cSuccessNone0.054970s0.118229s
Success
mkfifo_test.cSuccessNone0.061238s0.157962s
Success
mknod.cSuccessNone0.053585s0.124611s
Success
nocancel_io.cSuccessNone0.057594s0.141942s
Success
open.cSuccessNone0.049963s0.107674s
Success
openat.cSuccessNone0.050212s0.111570s
Success
path_conversion_safety.cSuccessNone0.059665s0.136105s
Success
ppoll.cSuccessNone0.059196s0.125738s
Success
pread_pwrite.cSuccessNone0.052023s0.120797s
Success
preadv_pwritev.cSuccessNone0.057557s0.133086s
Success
printf.cSuccessNone0.047956s0.102787s
Success
prlimit64.cSuccessNone0.049627s0.106636s
Success
read.cSuccessNone0.058743s0.129876s
Success
readbytes.cSuccessNone0.051567s0.109349s
Success
readdir_basic.cSuccessNone0.059567s0.151357s
Success
readlink.cSuccessNone0.055140s0.123651s
Success
readlinkat.cSuccessNone0.057538s0.126916s
Success
readv_writev_test.cSuccessNone0.056551s0.127633s
Success
rename.cSuccessNone0.056614s0.118492s
Success
sc-writev.cSuccessNone0.053070s0.116898s
Success
stat.cSuccessNone0.056482s0.127135s
Success
statfs.cSuccessNone0.051188s0.113167s
Success
symlink.cSuccessNone0.058654s0.148175s
Success
sync_file_range.cSuccessNone0.052846s0.111591s
Success
timespec_time_t_compat.cSuccessNone0.053067s0.109542s
Success
truncate.cSuccessNone0.056863s0.136753s
Success
unlink.cSuccessNone0.057084s0.151767s
Success
unlinkat.cSuccessNone0.056288s0.132550s
Success
write.cSuccessNone0.049133s0.102947s
Success
writeloop.cSuccessNone0.057419s0.118847s
Success
writepartial.cSuccessNone0.055504s0.111813s
Success
writev.cSuccessNone0.056683s0.127022s
Success
Math Tests
math_link_smoke.cSuccessNone0.059815s0.108516s
Success
math_tests.cSuccessNone0.063799s0.140028s
Success
printf_float.cSuccessNone0.060137s0.133095s
Success
Memory Tests
brk.cSuccessNone0.053764s0.114559s
Success
fork_large_memory.cSuccessNone0.087507s0.379343s
Success
malloc.cSuccessNone0.051139s0.103349s
Success
malloc_large.cSuccessNone0.051651s0.104558s
Success
memcpy.cSuccessNone0.052555s0.106119s
Success
memory_error_test.cSuccessNone0.057105s0.136102s
Success
mmap.cSuccessNone0.048409s0.105915s
Success
mmap_aligned.cSuccessNone0.050541s0.119453s
Success
mmap_complicated.cSuccessNone0.055484s0.129507s
Success
mmap_file.cSuccessNone0.056078s0.120465s
Success
mmap_shared.cSuccessNone0.055580s0.126916s
Success
mmaptest.cSuccessNone0.050671s0.110774s
Success
mprotect.cSuccessNone0.050225s0.108799s
Success
mprotect_boundary.cSuccessNone0.050824s0.118134s
Success
mprotect_end_region.cSuccessNone0.049843s0.113312s
Success
mprotect_middle_region.cSuccessNone0.052575s0.115372s
Success
mprotect_multiple_times.cSuccessNone0.051081s0.113426s
Success
mprotect_same_value.cSuccessNone0.049878s0.111776s
Success
mprotect_spanning_regions.cSuccessNone0.050374s0.128727s
Success
munmap_adjacent_shm.cSuccessNone0.052470s0.128044s
Success
sbrk.cSuccessNone0.053564s0.110125s
Success
segfault.cSuccessNone0.059791s0.143066s
Success
shm.cSuccessNone0.054535s0.130115s
Success
shmtest.cSuccessNone0.052676s0.112414s
Success
thread_malloc_sequential.cSuccessNone0.058183s0.162011s
Success
vtable.cSuccessNone0.059324s0.121636s
Success
Networking Tests
accept4.cSuccessNone0.060973s0.132285s
Success
dns_resolve_test.cSuccessNone0.056725s0.122702s
Success
dnstest.cSuccessNone0.056290s0.118861s
Success
epoll_badfd.cSuccessNone0.052616s0.111770s
Success
epoll_edge_triggered.cSuccessNone0.212637s0.382764s
Success
epollcreate1.cSuccessNone0.057460s0.134212s
Success
error_handling_net.cSuccessNone0.062993s0.193761s
Success
getaddrinfo_test.cSuccessNone0.059370s0.153134s
Success
getaddrinfo_unspec.cSuccessNone0.067600s0.179508s
Success
gethostname.cSuccessNone0.053379s0.109578s
Success
getifaddrs.cSuccessNone0.057790s0.121448s
Success
getsockname.cSuccessNone0.060837s0.126706s
Success
getsockopt.cSuccessNone0.060221s0.165061s
Success
ipv6_basic.cSuccessNone0.060021s0.164355s
Success
makepipe.cSuccessNone0.050716s0.107833s
Success
nonblocking_eagain.cSuccessNone0.061443s0.168964s
Success
pipe.cSuccessNone0.059116s0.131600s
Success
pipe2.cSuccessNone0.058517s0.121040s
Success
pipeinput.cSuccessNone0.059058s0.145385s
Success
pipeinput2.cSuccessNone0.060672s0.149930s
Success
pipeonestring.cSuccessNone0.060717s0.146327s
Success
pipepong.cSuccessNone0.057617s0.147469s
Success
pipewrite.cSuccessNone0.052153s0.117799s
Success
poll.cSuccessNone0.056859s0.116217s
Success
recvfrom-sendto.cSuccessNone0.059733s0.130920s
Success
sendmsg_recvmsg_test.cSuccessNone0.058384s0.130526s
Success
serverclient.cSuccessNone0.057185s0.135495s
Success
shutdown.cSuccessNone0.061703s0.133546s
Success
shutdown_fork.cSuccessNone0.057862s0.135237s
Success
simple-select.cSuccessNone0.059281s0.146946s
Success
simple_epoll.cSuccessNone0.057114s0.127912s
Success
socket.cSuccessNone0.055313s0.118094s
Success
socket_cloexec.cSuccessNone0.054934s0.113305s
Success
socket_options_advanced.cSuccessNone0.062170s0.174080s
Success
socketepoll.cSuccessNone0.056153s0.117712s
Success
socketpair.cSuccessNone0.055962s0.129552s
Success
socketselect.cSuccessNone0.056548s0.126720s
Success
udp_send_recv.cSuccessNone0.165391s0.271490s
Success
uds-getsockname.cSuccessNone0.056140s0.121301s
Success
uds-nb-select.cSuccessNone2.064951s2.179198s
Success
uds-serverclient.cSuccessNone0.061625s0.152209s
Success
uds-socketselect.cSuccessNone0.058035s0.133154s
Success
uds_listen_poll.cSuccessNone1.064489s1.163496s
Success
writev_socket.cSuccessNone0.061595s0.162234s
Success
Process Tests
barrier_test.cSuccessNone0.055509s0.126237s
Success
chain_thread.cSuccessNone1.057977s1.136182s
Success
ctor_syscall_test.cSuccessNone0.048305s0.107199s
Success
cxa_atexit_test.cSuccessNone0.053056s0.111245s
Success
exec_non_utf8.cSuccessNone0.057022s0.118552s
Success
execve_shebang.cSuccessNone0.059104s0.118596s
Success
exit.cSuccessNone0.055344s0.112358s
Success
exit_failure.cSuccessNone0.060094s0.131266s
Success
exit_group_thread.cSuccessNone0.058967s0.136865s
Success
exit_status_first_wins.cFailureFailure_native_compiling0.036719sN/A
Native execution: /tmp/wasmtest_artifacts_1_yjextx/process_tests/deterministic/exit_status_first_wins.c:25:9: error: call to undeclared library function 'exit' with type 'void (int) __attribute__((noreturn))'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
   25 |         exit(1);
      |         ^
/tmp/wasmtest_artifacts_1_yjextx/process_tests/deterministic/exit_status_first_wins.c:25:9: note: include the header <stdlib.h> or explicitly provide a declaration for 'exit'
1 error generated.
flockfile_test.cSuccessNone0.057942s0.136104s
Success
fork2malloc.cSuccessNone0.058688s0.128780s
Success
fork_select.cSuccessNone0.056834s0.134928s
Success
fork_simple.cSuccessNone0.057200s0.126696s
Success
fork_syscall.cSuccessNone0.062016s0.361756s
Success
fork_tls_ctype.cSuccessNone0.059103s0.147514s
Success
forkandopen.cSuccessNone0.057801s0.140658s
Success
forkdup.cSuccessNone0.061580s0.133402s
Success
forkexecuid.cSuccessNone0.056870s0.142637s
Success
forkexecv-arg.cSuccessNone0.056815s0.132146s
Success
forkexecv.cSuccessNone0.055722s0.129185s
Success
forkfiles.cSuccessNone0.058256s0.135218s
Success
forkmalloc.cSuccessNone0.060036s0.123156s
Success
forknodup.cSuccessNone0.057962s0.137176s
Success
function-ptr.cSuccessNone0.052738s0.109808s
Success
getegid_syscall.cSuccessNone0.056888s0.277526s
Success
getgid_syscall.cSuccessNone0.057704s0.281014s
Success
getpid.cSuccessNone0.051782s0.107631s
Success
getpid_syscall.cSuccessNone0.059718s0.296794s
Success
getppid.cSuccessNone0.058364s0.124255s
Success
getppid_syscall.cSuccessNone0.060712s0.253872s
Success
getuid.cSuccessNone0.058542s0.117961s
Success
getuid_syscall.cSuccessNone0.089697s0.211056s
Success
hello-arg.cSuccessNone0.048658s0.108645s
Success
hello.cSuccessNone0.048174s0.103810s
Success
longjmp.cSuccessNone0.049854s0.113654s
Success
mutex.cSuccessNone2.061741s2.129636s
Success
printf_deadlock_smoke.cSuccessNone0.065601s0.163553s
Success
printf_thread_test.cSuccessNone0.057661s0.134123s
Success
sem_forks.cSuccessNone0.059476s0.145472s
Success
setsid.cSuccessNone0.051073s0.106230s
Success
template.cSuccessNone0.057332s0.149217s
Success
test_exec_nofork.cSuccessNone0.058217s0.131463s
Success
test_unlink_open_file.cSuccessNone0.052110s0.109532s
Success
thread-guard.cSuccessNone0.055064s0.126845s
Success
thread-test.cSuccessNone0.054469s0.120227s
Success
thread.cSuccessNone0.055521s0.137645s
Success
thread_cageid_race.cSuccessNone0.053091s0.169791s
Success
tls_test.cSuccessNone0.056172s0.133058s
Success
uname.cSuccessNone0.051359s0.106195s
Success
wait.cSuccessNone0.054473s0.132415s
Success
waitpid_anychild.cSuccessNone0.056991s0.128579s
Success
waitpid_syscall.cSuccessNone1.059036s1.176575s
Success
waitpid_wnohang.cSuccessNone0.057932s0.130083s
Success
Signal Tests
alarm.cSuccessNone7.055545s7.148332s
Success
eintr_fork_signal.cSuccessNone1.058070s1.139206s
Success
kill.cSuccessNone1.055347s1.127333s
Success
setitimer.cSuccessNone7.055918s7.150622s
Success
sigalrm.cSuccessNone2.056568s2.131707s
Success
sigaltstack.cSuccessNone0.057139s0.129257s
Success
sigchld.cSuccessNone1.057637s1.125865s
Success
signal-fork.cSuccessNone4.057302s4.127949s
Success
signal-simple.cSuccessNone0.057416s0.117243s
Success
signal_SIGCHLD.cSuccessNone0.055687s0.131567s
Success
signal_fork.cSuccessNone0.052990s0.129194s
Success
signal_int_ignored.cSuccessNone2.056197s2.132448s
Success
signal_kill_cleanup.cSuccessNone1.054940s1.121664s
Success
signal_procmask.cSuccessNone0.052300s0.117201s
Success
signal_read_interrupt.cSuccessNone0.561663s0.634033s
Success
signal_recursive.cSuccessNone0.051284s0.120474s
Success
signal_sa_mask.cSuccessNone0.050692s0.111599s
Success
signal_select_interrupt.cSuccessNone0.559995s0.643797s
Success
signal_write_interrupt.cSuccessNone1.058057s1.135083s
Success
sigpipe.cSuccessNone1.059068s1.134760s
Success
sigprocmask.cSuccessNone1.055780s1.122944s
Success
Fail Tests

Summary

MetricCount
Total Test Cases4
Number of Successes4
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

Test Results by Category

Test CaseStatusError TypeNative TimeWasm TimeOutput
Dylink Tests
dlerror.cSuccessNone0.049914s0.108160s
Success
Memory Tests
mmap-negative1.cSuccessNone0.137726s0.123101s
Success
mmap-negative2.cSuccessNone0.120906s0.124607s
Success
Signal Tests
signal_resethand.cSuccessNone1.057855s1.126714s
Success

C++ harness

Summary

MetricValue
Total1
Success1
Failures0
Compile failures0
Runtime failures0
Output mismatch0
Timeouts0

Cases

TestStatusError typeNative timeWasm timeOutput
tests/unit-tests/cpp/sort.cppSuccess0.559068s10.052095s
LIBCPP_SORT_OK 1 2 3

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 7, 2026

End-to-End Test Report

Test Preview

grate harness

Grate Test Report

MetricValue
Total14
Success14
Failures0
Compile Failures0
Runtime Failures0
Timeout Failures0
Missing Pair Failures0

Cases

TestStatusError TypeOutput
concurrent-request/geteuid_grate.cSuccess
STDOUT:
[Grate|geteuid] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 3
[Cage | geteuid] PASS: 1000000 calls returned 10
[Grate|geteuid] PASS

STDERR:

concurrent-request/race-test_grate.cSuccess
STDOUT:
pass

STDERR:

concurrent-request/thread_race_grate.cSuccess
STDOUT:
[thread_race] Registering handler for cage 2 in grate 1 with fn ptr addr: 3
[thread_race] PASS: 20 threads x 100000 calls returned 10
[thread_race] PASS

STDERR:

copy-data-between-cages/cp-stncpy_grate.cSuccess
STDOUT:
[cage] pathname addr=0xfffb6ff9
[cage] pathname='random'
[Grate|open] intercepts open call: thiscage=1, arg1cage=2
[Grate|open] copied pathname: random
[cage] fd=10

STDERR:

copy-data-between-cages/cpdata_grate.cSuccess
STDOUT:
[Grate|open] intercepts open call: thiscage=1, arg1cage=2
[Grate|open] copied pathname: random
[cage] fd=10

STDERR:

interposing-calls/fork-with-newret_grate.cSuccess
STDOUT:
[Grate|interpose-fork] Registering fork handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|interpose-fork] Handling function ptr: 3 from cage: 1
[Grate|interpose-fork] In fork_grate 1 handler for cage: 1
[Cage] Forked process with PID: 10
[Grate|interpose-fork] PASS

STDERR:

interposing-calls/interpose-exec_grate.cSuccess
STDOUT:
[Grate|interpose-exec] Registering exec handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|interpose-exec] Handling function ptr: 3 from cage: 1
[Grate|interpose-exec] In exec_grate 1 handler for cage: 1
[Grate|interpose-exec] Handling function ptr: 3 from cage: 1
[Grate|interpose-exec] In exec_grate 1 handler for cage: 1
Exec successful, argv[1]: --execd
[Grate|interpose-exec] PASS

STDERR:

interposing-calls/interpose-exit_grate.cSuccess
STDOUT:
[Grate|interpose-exit] Registering exit handler for cage 2 in grate 1 with fn ptr addr: 3
Exiting...

[Grate|interpose-exit] PASS

STDERR:

interposing-calls/interpose-fork_grate.cSuccess
STDOUT:
[Grate|interpose-fork] Registering fork handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|interpose-fork] Handling function ptr: 3 from cage: 1
[Grate|interpose-fork] In fork_grate 1 handler for cage: 1
[Grate|interpose-fork] PASS

STDERR:

interposing-calls/interpose-mmap_grate.cSuccess
STDOUT:
[Grate|interpose-mmap] Registering mmap handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
[Grate|interpose-mmap] Handling function ptr: 3 from cage: 1
[Grate|interpose-mmap] In mmap_grate 1 handler for cage: 1
mmap test: PASS
[Grate|interpose-mmap] PASS

STDERR:

interposing-calls/interpose-register_grate.cSuccess
STDOUT:
[Grate|interpose-register] Registering register_handler for cage 2 in grate 1 with fn ptr addr: 4
[cage] registering 107. grateid: 2 cageid: 3
[Grate|interpose-register] Handling function ptr: 4 from cage: 1
[Grate|interpose-register] In register_grate 1 handler for cage: 1
[Grate|geteuid] Registering geteuid handler for cage 1 in grate 1 with fn ptr addr: 3
[Grate|interpose-register] Handling function ptr: 3 from cage: 1
[Grate|interpose-register] In register_grate 1 handler for cage: 1
[Grate|interpose-register] PASS

STDERR:

multi-register_grate.cSuccess
STDOUT:
[Grate|multi-register_grate] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 4
[Grate|multi-register_grate] Registering getuid handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|multi-register_grate] Handling function ptr: 4 from cage: 1
[Grate|multi-register_grate] In multi-register_grate 1 handler for cage: 1
[Grate|multi-register_grate] Handling function ptr: 3 from cage: 1
[Grate|multi-register_grate] In multi-register_grate 1 handler for cage: 1
[Cage | multi-register] PASS: geteuid=10, getuid=20
[Grate|multi-register] PASS

STDERR:

simple-tests/diff-cage-args_grate.cSuccess
STDOUT:
[Grate|diff-cage-args] Handling function ptr: 3 from cage: 1
[Grate|diff-cage-args] In open_grate 1 handler for cage: 1
Hello world. FD=-1
[Grate|diff-cage-args] Handling function ptr: 4 from cage: 1
Goodbye world! ret=4321 buf=helloworld
[Grate|diff-cage-args] PASS

STDERR:

simple-tests/geteuid_grate.cSuccess
STDOUT:
[Grate|geteuid] Registering geteuid handler for cage 2 in grate 1 with fn ptr addr: 3
[Grate|geteuid] Handling function ptr: 3 from cage: 1
[Grate|geteuid] In geteuid_grate 1 handler for cage: 1
[Cage | geteuid] PASS: geteuid ret = 10
[Grate|geteuid] PASS

STDERR:

static harness

Test Report

Deterministic Tests

Summary

MetricCount
Total Test Cases3
Number of Successes3
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

Test Results by Category

Test CaseStatusError TypeNative TimeWasm TimeOutput
Static Tests
fork_simple.cSuccessNone0.055290s4.352681s
Success
thread.cSuccessNone0.046815s4.405897s
Success
tls_test.cSuccessNone0.068949s4.437066s
Success
Fail Tests

Summary

MetricCount
Total Test Cases0
Number of Successes0
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

wasm harness

Test Report

Deterministic Tests

Summary

MetricCount
Total Test Cases214
Number of Successes214
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

Test Results by Category

Test CaseStatusError TypeNative TimeWasm TimeOutput
File Tests
chartests.cSuccessNone0.046941s0.138363s
Success
chdir_getcwd.cSuccessNone0.046795s0.108783s
Success
chmod.cSuccessNone0.052759s0.117419s
Success
clock_gettime_highlevel.cSuccessNone0.117329s0.152923s
Success
clock_gettime_simple.cSuccessNone0.043435s0.098453s
Success
cloexec.cSuccessNone0.051676s0.122948s
Success
close.cSuccessNone0.059835s0.128555s
Success
creat_access.cSuccessNone0.049852s0.108473s
Success
doubleclose.cSuccessNone0.042175s0.090907s
Success
dup.cSuccessNone0.043780s0.108372s
Success
dup2.cSuccessNone0.047817s0.105983s
Success
dup3.cSuccessNone0.046389s0.107539s
Success
dupwrite.cSuccessNone0.049295s0.104593s
Success
etc_conf.cSuccessNone0.044442s0.109106s
Success
fchdir.cSuccessNone0.052230s0.120370s
Success
fchmod.cSuccessNone0.052666s0.120565s
Success
fcntl.cSuccessNone0.048627s0.122280s
Success
fdatasync.cSuccessNone0.048426s0.103058s
Success
filetest.cSuccessNone0.049242s0.101232s
Success
filetest1000.cSuccessNone0.058177s0.116919s
Success
flock.cSuccessNone0.063662s0.144244s
Success
fstat.cSuccessNone0.051977s0.118685s
Success
fstatfs.cSuccessNone0.044010s0.100475s
Success
fsync.cSuccessNone0.049198s0.109034s
Success
ftruncate.cSuccessNone0.054467s0.204828s
Success
getcwd.cSuccessNone0.046467s0.097663s
Success
getcwd_null.cSuccessNone0.049932s0.112254s
Success
getpgid.cSuccessNone0.044172s0.094967s
Success
getrandom.cSuccessNone0.050132s0.120204s
Success
ioctl.cSuccessNone0.053094s0.113807s
Success
link.cSuccessNone0.053234s0.149219s
Success
locale_test.cSuccessNone0.064295s0.310279s
Success
lseek.cSuccessNone0.054358s0.195475s
Success
lstat.cSuccessNone0.053031s0.126270s
Success
mkdir_rmdir.cSuccessNone0.050489s0.109496s
Success
mkfifo_test.cSuccessNone0.054915s0.151582s
Success
mknod.cSuccessNone0.049638s0.117259s
Success
nocancel_io.cSuccessNone0.054526s0.136688s
Success
open.cSuccessNone0.044257s0.095557s
Success
openat.cSuccessNone0.046040s0.106904s
Success
path_conversion_safety.cSuccessNone0.053883s0.128015s
Success
ppoll.cSuccessNone0.053348s0.116993s
Success
pread_pwrite.cSuccessNone0.047257s0.113317s
Success
preadv_pwritev.cSuccessNone0.051530s0.122607s
Success
printf.cSuccessNone0.040941s0.090379s
Success
prlimit64.cSuccessNone0.042815s0.099888s
Success
read.cSuccessNone0.050377s0.117122s
Success
readbytes.cSuccessNone0.046616s0.100444s
Success
readdir_basic.cSuccessNone0.054388s0.139624s
Success
readlink.cSuccessNone0.049928s0.116987s
Success
readlinkat.cSuccessNone0.052606s0.120827s
Success
readv_writev_test.cSuccessNone0.051538s0.120146s
Success
rename.cSuccessNone0.052972s0.113822s
Success
sc-writev.cSuccessNone0.047117s0.107054s
Success
stat.cSuccessNone0.050513s0.117003s
Success
statfs.cSuccessNone0.043724s0.098168s
Success
symlink.cSuccessNone0.052574s0.139602s
Success
sync_file_range.cSuccessNone0.047750s0.103064s
Success
timespec_time_t_compat.cSuccessNone0.047612s0.101399s
Success
truncate.cSuccessNone0.050991s0.126146s
Success
unlink.cSuccessNone0.052657s0.144718s
Success
unlinkat.cSuccessNone0.051397s0.125579s
Success
write.cSuccessNone0.043437s0.093140s
Success
writeloop.cSuccessNone0.052418s0.109233s
Success
writepartial.cSuccessNone0.050173s0.100700s
Success
writev.cSuccessNone0.052094s0.119510s
Success
Math Tests
math_link_smoke.cSuccessNone0.053398s0.099895s
Success
math_tests.cSuccessNone0.058902s0.130117s
Success
printf_float.cSuccessNone0.055216s0.123852s
Success
Memory Tests
brk.cSuccessNone0.047899s0.104175s
Success
fork_large_memory.cSuccessNone0.079181s0.367360s
Success
malloc.cSuccessNone0.046852s0.097041s
Success
malloc_large.cSuccessNone0.048062s0.095234s
Success
memcpy.cSuccessNone0.045579s0.095799s
Success
memory_error_test.cSuccessNone0.051858s0.130629s
Success
mmap.cSuccessNone0.044002s0.096978s
Success
mmap_aligned.cSuccessNone0.044342s0.109172s
Success
mmap_complicated.cSuccessNone0.051199s0.121216s
Success
mmap_file.cSuccessNone0.050735s0.110057s
Success
mmap_shared.cSuccessNone0.049060s0.115024s
Success
mmaptest.cSuccessNone0.046998s0.101005s
Success
mprotect.cSuccessNone0.046392s0.097958s
Success
mprotect_boundary.cSuccessNone0.043366s0.107584s
Success
mprotect_end_region.cSuccessNone0.043230s0.102636s
Success
mprotect_middle_region.cSuccessNone0.043374s0.104295s
Success
mprotect_multiple_times.cSuccessNone0.044173s0.101861s
Success
mprotect_same_value.cSuccessNone0.044383s0.101657s
Success
mprotect_spanning_regions.cSuccessNone0.044439s0.118378s
Success
munmap_adjacent_shm.cSuccessNone0.045687s0.119805s
Success
sbrk.cSuccessNone0.045405s0.099168s
Success
segfault.cSuccessNone0.050859s0.132258s
Success
shm.cSuccessNone0.050019s0.120148s
Success
shmtest.cSuccessNone0.046794s0.102435s
Success
thread_malloc_sequential.cSuccessNone0.051495s0.148013s
Success
vtable.cSuccessNone0.054522s0.116160s
Success
Networking Tests
accept4.cSuccessNone0.055689s0.126139s
Success
dns_resolve_test.cSuccessNone0.049130s0.110162s
Success
dnstest.cSuccessNone0.050711s0.108941s
Success
epoll_badfd.cSuccessNone0.044384s0.096580s
Success
epoll_edge_triggered.cSuccessNone0.207432s0.371275s
Success
epollcreate1.cSuccessNone0.051535s0.120431s
Success
error_handling_net.cSuccessNone0.059346s0.186045s
Success
getaddrinfo_test.cSuccessNone0.053442s0.146195s
Success
getaddrinfo_unspec.cSuccessNone0.054091s0.119424s
Success
gethostname.cSuccessNone0.043827s0.095072s
Success
getifaddrs.cSuccessNone0.052480s0.111215s
Success
getsockname.cSuccessNone0.057808s0.116357s
Success
getsockopt.cSuccessNone0.054769s0.147244s
Success
ipv6_basic.cSuccessNone0.055451s0.147391s
Success
makepipe.cSuccessNone0.043408s0.093005s
Success
nonblocking_eagain.cSuccessNone0.055543s0.156163s
Success
pipe.cSuccessNone0.053012s0.117793s
Success
pipe2.cSuccessNone0.053468s0.112058s
Success
pipeinput.cSuccessNone0.053789s0.134788s
Success
pipeinput2.cSuccessNone0.055246s0.141980s
Success
pipeonestring.cSuccessNone0.053120s0.132685s
Success
pipepong.cSuccessNone0.052920s0.141225s
Success
pipewrite.cSuccessNone0.047339s0.109104s
Success
poll.cSuccessNone0.050892s0.105786s
Success
recvfrom-sendto.cSuccessNone0.052504s0.117860s
Success
sendmsg_recvmsg_test.cSuccessNone0.052579s0.121075s
Success
serverclient.cSuccessNone0.051613s0.125574s
Success
shutdown.cSuccessNone0.053474s0.123409s
Success
shutdown_fork.cSuccessNone0.051110s0.121906s
Success
simple-select.cSuccessNone0.053710s0.134466s
Success
simple_epoll.cSuccessNone0.051815s0.114482s
Success
socket.cSuccessNone0.049851s0.106109s
Success
socket_cloexec.cSuccessNone0.050208s0.105658s
Success
socket_options_advanced.cSuccessNone0.058423s0.168714s
Success
socketepoll.cSuccessNone0.049810s0.108879s
Success
socketpair.cSuccessNone0.049932s0.121299s
Success
socketselect.cSuccessNone0.052882s0.118749s
Success
udp_send_recv.cSuccessNone0.161629s0.259702s
Success
uds-getsockname.cSuccessNone0.051715s0.108355s
Success
uds-nb-select.cSuccessNone2.061665s2.170049s
Success
uds-serverclient.cSuccessNone0.055217s0.140689s
Success
uds-socketselect.cSuccessNone0.051580s0.118091s
Success
uds_listen_poll.cSuccessNone1.057723s1.150657s
Success
writev_socket.cSuccessNone0.054351s0.146978s
Success
Process Tests
barrier_test.cSuccessNone0.050186s0.115570s
Success
chain_thread.cSuccessNone1.051309s1.123180s
Success
ctor_syscall_test.cSuccessNone0.041436s0.096671s
Success
cxa_atexit_test.cSuccessNone0.046878s0.100624s
Success
exec_non_utf8.cSuccessNone0.051443s0.109330s
Success
execve_shebang.cSuccessNone0.051445s0.108115s
Success
exit.cSuccessNone0.048954s0.098795s
Success
exit_failure.cSuccessNone0.051029s0.115345s
Success
exit_group_thread.cSuccessNone0.053579s0.123595s
Success
exit_status_first_wins.cSuccessNone0.053619s0.126364s
Success
flockfile_test.cSuccessNone0.051669s0.122968s
Success
fork2malloc.cSuccessNone0.053791s0.117710s
Success
fork_select.cSuccessNone0.049879s0.122195s
Success
fork_simple.cSuccessNone0.048869s0.111147s
Success
fork_syscall.cSuccessNone0.054867s0.332951s
Success
fork_tls_ctype.cSuccessNone0.054045s0.138210s
Success
forkandopen.cSuccessNone0.051949s0.127278s
Success
forkdup.cSuccessNone0.056991s0.123055s
Success
forkexecuid.cSuccessNone0.050022s0.126596s
Success
forkexecv-arg.cSuccessNone0.050520s0.117227s
Success
forkexecv.cSuccessNone0.047286s0.113488s
Success
forkfiles.cSuccessNone0.051547s0.124307s
Success
forkmalloc.cSuccessNone0.055535s0.116497s
Success
forknodup.cSuccessNone0.051714s0.124537s
Success
function-ptr.cSuccessNone0.046997s0.101745s
Success
getegid_syscall.cSuccessNone0.050710s0.258350s
Success
getgid_syscall.cSuccessNone0.053107s0.267222s
Success
getpid.cSuccessNone0.043828s0.094879s
Success
getpid_syscall.cSuccessNone0.055778s0.276370s
Success
getppid.cSuccessNone0.050832s0.113383s
Success
getppid_syscall.cSuccessNone0.053725s0.234237s
Success
getuid.cSuccessNone0.051721s0.104346s
Success
getuid_syscall.cSuccessNone0.051411s0.177194s
Success
hello-arg.cSuccessNone0.042356s0.095823s
Success
hello.cSuccessNone0.041867s0.091096s
Success
longjmp.cSuccessNone0.042866s0.098444s
Success
mutex.cSuccessNone2.055129s2.117499s
Success
printf_deadlock_smoke.cSuccessNone0.059770s0.146027s
Success
printf_thread_test.cSuccessNone0.048955s0.120106s
Success
sem_forks.cSuccessNone0.054290s0.153655s
Success
setsid.cSuccessNone0.044262s0.095188s
Success
template.cSuccessNone0.050308s0.137311s
Success
test_exec_nofork.cSuccessNone0.050310s0.116368s
Success
test_unlink_open_file.cSuccessNone0.046273s0.096295s
Success
thread-guard.cSuccessNone0.048344s0.114735s
Success
thread-test.cSuccessNone0.046918s0.106635s
Success
thread.cSuccessNone0.046251s0.104695s
Success
thread_cageid_race.cSuccessNone0.048266s0.159352s
Success
tls_test.cSuccessNone0.049226s0.120619s
Success
uname.cSuccessNone0.044748s0.095903s
Success
wait.cSuccessNone0.048440s0.120162s
Success
waitpid_anychild.cSuccessNone0.050830s0.117230s
Success
waitpid_syscall.cSuccessNone1.051632s1.164703s
Success
waitpid_wnohang.cSuccessNone0.050836s0.118081s
Success
Signal Tests
alarm.cSuccessNone7.050184s7.140183s
Success
eintr_fork_signal.cSuccessNone1.052692s1.156054s
Success
kill.cSuccessNone1.050468s1.120255s
Success
setitimer.cSuccessNone7.050376s7.136739s
Success
sigalrm.cSuccessNone2.050640s2.120795s
Success
sigaltstack.cSuccessNone0.052601s0.117632s
Success
sigchld.cSuccessNone1.052970s1.121111s
Success
signal-fork.cSuccessNone4.052183s4.116618s
Success
signal-simple.cSuccessNone0.051978s0.109615s
Success
signal_SIGCHLD.cSuccessNone0.050479s0.122349s
Success
signal_fork.cSuccessNone0.047637s0.121673s
Success
signal_int_ignored.cSuccessNone2.050624s2.120384s
Success
signal_kill_cleanup.cSuccessNone1.049506s1.112464s
Success
signal_procmask.cSuccessNone0.044881s0.105543s
Success
signal_read_interrupt.cSuccessNone0.555084s0.626580s
Success
signal_recursive.cSuccessNone0.044907s0.108976s
Success
signal_sa_mask.cSuccessNone0.045979s0.104108s
Success
signal_select_interrupt.cSuccessNone0.554906s0.628655s
Success
signal_write_interrupt.cSuccessNone1.054706s1.124865s
Success
sigpipe.cSuccessNone1.054413s1.128808s
Success
sigprocmask.cSuccessNone1.050927s1.112949s
Success
Fail Tests

Summary

MetricCount
Total Test Cases4
Number of Successes4
Number of Failures0
Number of Compilation Failure Native0
Number of Runtime Failure Native0
Number of Segmentation Fault Native0
Number of Timeout During Native0
Number of Lind Wasm Compile Failure0
Number of Lind Wasm Runtime Failure0
Number of Lind Wasm Segmentation Failure0
Number of Timeout During Lind Wasm run0
Number of Unknown Failure0
Number of C Compiler and Wasm Output mismatch0
Number of Fail Test: Native Succeeded (Should Fail)0
Number of Fail Test: Wasm Succeeded (Should Fail)0
Number of Fail Test: Both Native and Wasm Succeeded (Should Fail)0
Number of Fail Test: Native Compilation Failure (Should Succeed)0
Number of Fail Test: Wasm Compilation Failure (Should Succeed)0

Test Results by Category

Test CaseStatusError TypeNative TimeWasm TimeOutput
Dylink Tests
dlerror.cSuccessNone0.043824s0.098689s
Success
Memory Tests
mmap-negative1.cSuccessNone0.132608s0.103829s
Success
mmap-negative2.cSuccessNone0.113911s0.124141s
Success
Signal Tests
signal_resethand.cSuccessNone1.051960s1.116202s
Success

C++ harness

Summary

MetricValue
Total1
Success1
Failures0
Compile failures0
Runtime failures0
Output mismatch0
Timeouts0

Cases

TestStatusError typeNative timeWasm timeOutput
tests/unit-tests/cpp/sort.cppSuccess0.657764s11.760026s
LIBCPP_SORT_OK 1 2 3

@rennergade
Copy link
Copy Markdown
Contributor

One concern: the Signaled → 1 mapping at sys_calls.rs:444 and signal.rs:56 reintroduces the same "last thread wins" non-determinism the PR is trying to eliminate, just in the signal-termination case instead of the explicit-exit case. The Terminate handler at signal.rs:115 calls exit_call(caller, 128 + signo, 0) directly, but a sibling thread that gets epoch-killed and exits via the thread_check_killed branch will read Signaled(_, _) from final_exit_status and pass 1 instead — so whichever thread happens to call the trampoline last determines whether the wasmtime/OS-level exit code is 128 + signo or 1. waitpid's WIFSIGNALED decoding still works because it goes through encode_wait_status, but anyone reading the process's shell-level $? sees a non-deterministic value. Both mapping sites should produce 128 + (signo & 0x7f) to match what the Terminate path already passes.

@qianxichen233
Copy link
Copy Markdown
Contributor Author

One concern: the Signaled → 1 mapping at sys_calls.rs:444 and signal.rs:56 reintroduces the same "last thread wins" non-determinism the PR is trying to eliminate, just in the signal-termination case instead of the explicit-exit case. The Terminate handler at signal.rs:115 calls exit_call(caller, 128 + signo, 0) directly, but a sibling thread that gets epoch-killed and exits via the thread_check_killed branch will read Signaled(_, _) from final_exit_status and pass 1 instead — so whichever thread happens to call the trampoline last determines whether the wasmtime/OS-level exit code is 128 + signo or 1. waitpid's WIFSIGNALED decoding still works because it goes through encode_wait_status, but anyone reading the process's shell-level $? sees a non-deterministic value. Both mapping sites should produce 128 + (signo & 0x7f) to match what the Terminate path already passes.

There are two different exit routine, one is for wasm module exit code (which propogates exit code via wasm semantic), and one is for waitpid semantic exit code (which records the exit code in the cage struct). the wasm module exit code currently isn't getting handled (e.g. the exit code of forked module is silently dropped). This is like thread exit code v.s. process exit code, where we currently only handled process exit code but not thread exit code. This PR basically removed recording of thread exit code (since it previously would overwrite process exit code) and force it to 1. This is a temporary solution before we add/fix the support for thread exit code (which will need to implement pthread_exit as well). The process exit code recorded on cage struct remains unchanged.

@rennergade rennergade merged commit 9c41686 into main May 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants