Shared memory errors
zinc_create fails with AlreadyExists (-17)
A region with that name already exists in /dev/shm/. Either:
- An earlier process crashed without cleaning up.
- Another process is actively using the region.
zinc_create fails with InvalidSize (-22)
Capacity must be a positive multiple of the system page size (typically 4096 bytes). The error includes the required page size.
zinc_open fails with NotFound (-2)
No region with that name exists. The creating process may have already closed and unlinked it, or it hasn’t been created yet. Ensure the creator is running and using the same name. Region names are case-sensitive.
PermissionDenied (-1)
On Linux, shared memory objects are created with mode 0600 (owner read/write). If another user created the region, your process can’t open it. All processes sharing a region must run as the same user.
Library not found errors
Python: OSError: cannot load library
Node: npm run build fails
The Node adapter uses napi-rs. If npm run build fails with missing symbols:
../../core, so you need the full repo checked out.
Go: cgo linker errors
Java: UnsatisfiedLinkError
libzinc_core.so on java.library.path. Set it:
C#: DllNotFoundException
libzinc_core.so / libzinc_core.dylib to the working directory or set LD_LIBRARY_PATH / DYLD_LIBRARY_PATH before running .NET tests.
Bun: dlopen fails
Bun’s bun:ffi looks for the library at a path relative to the source file. By default it expects:
Deno: --allow-ffi required
Deno’s FFI requires the --allow-ffi permission:
macOS-specific issues
Wait burns CPU
On macOS,wait() uses an adaptive spin loop because futex doesn’t exist. A waiting thread will consume CPU for the duration of the wait. This is by design.
Mitigations:
- Keep timeouts short (< 100ms).
- Use
notify()+ manual polling for very long waits. - Consider using a
dispatch_semaphorein shared memory on top of a Zinc region if you need efficient sleeping waits on macOS.
Region names not visible in filesystem
Unlike Linux, macOS shared memory objects don’t appear as files.ls /dev/shm/ won’t work. Use a coordination mechanism (file lock, socket, env var) to tell processes which names to use.
shm_open fails with ENOMEM
macOS has a very low default limit for shared memory. Check:
Linux-specific issues
/dev/shm permissions
Some container runtimes mount /dev/shm with restricted permissions:
PermissionDenied, ensure the mount has the sticky bit (t) set and is world-writable. In Docker, add:
Too many regions (ENFILE / EMFILE)
Each open region holds a file descriptor. The default per-process limit is typically 1024. Raise it:
vm.max_map_count exhaustion
Each mmap call creates a mapping entry in the kernel’s VMA tree. If you open many regions, you may hit the limit:
General debugging
Enable verbose errors
The core library returns error codes as negativeerrno values. Most adapter wrappers try to map these to readable messages. If you get a cryptic numeric error, look it up:
Check for zombie regions
Regions persist in/dev/shm/ if the creator crashes without unlinking. To find them:
fuser or lsof), you can safely remove the file.
Verify the core library is compatible
include/zinc.h) and the library in sync, they’re built together.
File descriptor usage
Each
zinc_create or zinc_open holds one file descriptor from shm_open and one anonymous descriptor from mmap. Both are released on zinc_close. If your process opens many regions, mind the per-process FD limit.