Skip to content

Fix getpid errno assertions in multi_thread test#96

Merged
petreeftime merged 1 commit intorust-vmm:mainfrom
rschmitt:main
Apr 6, 2026
Merged

Fix getpid errno assertions in multi_thread test#96
petreeftime merged 1 commit intorust-vmm:mainfrom
rschmitt:main

Conversation

@rschmitt
Copy link
Copy Markdown
Contributor

@rschmitt rschmitt commented Feb 25, 2026

There are two issues with this test.

  1. On my Linux 5.10 machine, errno is set to ENOENT as soon as the test begins. Somehow the Rust test harness is making a syscall that is failing, and that stale value is getting read from errno and causing the assertion failure early in test_tsync. This is fixed by simply clearing errno before calling getpid.
  2. getpid() from libc does not set errno on either glibc or musl, hence the strange errno == 0 assertion after making a getpid call that failed. This is fixed by going through the generic syscall() function, which does set errno so that we can compare it to the expected EPERM.

@rschmitt rschmitt changed the title fix(seccompiler): fix getpid errno assertions in multi_thread test Fix getpid errno assertions in multi_thread test Feb 25, 2026
@rschmitt rschmitt force-pushed the main branch 3 times, most recently from 1896dc3 to d2958a8 Compare February 25, 2026 20:36
Comment thread tests/multi_thread.rs
let pid = unsafe { libc::getpid() };
// Clear any stale `errno` value
unsafe { *libc::__errno_location() = 0; }
// Go through the generic `syscall` function, as `getpid` does not set `errno`
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's strictly true, but I think that glibc might do caching, so it won't always call the syscall, which is what we want in this case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that's strictly true

It's trivially true for musl: kraj/musl@d878dce

glibc is weirder because the implementations of functions like getpid are all generated, but this blog post explains the syscall wrapper generation and mentions getpid specifically:

There are three kind of system call which is defined by ‘T_PSEUDO’, ‘T_PSEUDO_NOERRNO’ and ‘T_PSEUDO_ERRVAL’. If ‘SYSCALL_NOERRNO’ is defined then the system call is wrapped by ‘T_PSEUDO_NOERRNO’, this means the wrapper doesn’t return error code, for example the ‘getpid’ and ‘umask’ system call.

The args for getpid are defined in glibc here as Ei:, and E indicates that errno is not set by the call.

I think that glibc might do caching

Not since glibc 2.25 (2017-02-05): https://sourceware.org/glibc/wiki/Release/2.25#Calls_to_getpid_are_no_longer_cached

petreeftime
petreeftime previously approved these changes Feb 26, 2026
@petreeftime
Copy link
Copy Markdown
Collaborator

There are two issues with this test.

1. On my Linux 5.10 machine, `errno` is set to `ENOENT` as soon as the
   test begins. Somehow the Rust test harness is making a syscall that
   is failing, and that stale value is getting read from `errno` and
   causing the assertion failure early in `test_tsync`. This is fixed by
   simply clearing `errno` before calling `getpid`.
2. `getpid()` from libc does not set `errno` on either glibc or musl,
   hence the strange `errno == 0` assertion after making a `getpid` call
   that failed. This is fixed by doing through the generic `syscall()`
   function, which _does_ set `errno` so that we can compare it to the
   expected `EPERM`.

Signed-off-by: Ryan Schmitt <rschmitt@pobox.com>
@petreeftime petreeftime merged commit becf237 into rust-vmm:main Apr 6, 2026
1 of 2 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