ziglang / zig

General-purpose programming language and toolchain for maintaining robust, optimal, and reusable software.
https://ziglang.org
MIT License
33.69k stars 2.47k forks source link

Compiling as a library in debug mode for linking into a Unikraft kernel fails when logging due to Thread.getCurrentId implementation #20546

Open elerch opened 2 months ago

elerch commented 2 months ago

Zig Version

0.13.0

Steps to Reproduce and Observed Behavior

  1. zig init
  2. add std.log.warn("hello world", .{}); to the add function in src/root.zig
  3. add lib.bundle_compiler_rt = true; lib.linkLibC(); to build.zig
  4. zig build
  5. Copy the resultant library into the helloworld-c native unikraft directory (https://github.com/unikraft/catalog/tree/4219b32f3d1cd9fbaa7d50861cc1acd81bfc2362/native/helloworld-c)
  6. Configure and compile unikernel with kraft build --plat qemu --arch x86_64
  7. kraft run --plat qemu --arch x86_64

Program crashes

Expected Behavior

Program should link and run successfully, as it does when the zig library is compiled with -Doptimize=ReleaseSafe

elerch commented 2 months ago

I am happy to add more details and create a repo with the exact unikraft configuration, but I'm not entirely sure this should be considered a bug, so this is for search-foo in case the other person on the Internet interested in this niche case runs across the problem, and possibly for consideration.

The difference between release mode and debug mode in my problem description above comes down to the mutex that's used for std.log. In debug mode, the Linux implementation will utilize the thread ID to avoid contention. In release mode it does not.

std.Thread.getCurrentId on linux ultimately performs a syscall, which appears to be the appropriate thing according to the man page. It was added to glibc in 2.30. Unikraft does not have syscall emulation for this operation, so by that logic, this could be a unikraft bug.

However, there is no way for me to redirect the logic in stdlib away from the syscall to the calling of a libc function, which will work appropriately in Unikraft (if you configure in process support). So from that logic, this could be a standard library bug.

A third option is that one could say "what are you doing filing a bug on Linux libraries when this is a unikernel, and not Linux?". That...is a fair argument to make, but introducing a new operating system into the standard library for (what at the moment appears to be) a single change to provide a solution, and only in debug mode, seems a bit over kill.

So, I humbly submit to the project this bug/enhancement/question for consideration.