I freely admit to having Claude.ai's help in tracking down this issue and explaining the cause, but nevertheless think it has merit, since the workaround does sidestep it. Hopefully this gives enough information to track down where the box64 emulation is mangling the directory name.
Environment
- Box64 v0.4.3, ARM64 Dynarec
- Wine 11.0 stable (x86-64)
- Neoverse-N1, 4K pagesize
- Docker container on ARM64 host
Problem
Wine fails on startup with:
wine: chdir to /tmp/.wine-1001/server-38-53f7100000000 : No such file or directory
The directory that actually gets created is server-38-53f71. The trailing 00000000 is not present on the created directory, but Wine expects it when it tries to chdir into it.
The values 38 and 53f71 are the st_dev and st_ino of the WINEPREFIX directory.
Cause
Both wineserver and ntdll build the server directory name from the same stat values using the same format string.
server/request.c — create_server_dir() (creates the directory):
asprintf(&server_dir, "%s/server-%llx-%llx", base_dir,
(unsigned long long)st.st_dev, (unsigned long long)st.st_ino);
dlls/ntdll/unix/server.c — server_dir_init() (looks up the directory):
asprintf(&dir, "/tmp/.wine-%u/server-%llx-%llx", getuid(),
(unsigned long long)dev, (unsigned long long)ino);
On native x86_64 they always match.
Under Box64, wineserver calls asprintf through the native-wrapped libc path (Using native(wrapped) libc.so.6) and produces the correct short result server-38-53f71. The asprintf call inside ntdll.so runs from emulated x86_64 code (Using emulated .../ntdll.so) and produces server-38-53f7100000000 — as if the upper 32 bits of the unsigned long long variadic argument contain garbage or the argument layout is wrong.
Reproduction
- Install Wine 11.0 stable x86-64 on ARM64 with Box64
- Set a WINEPREFIX and run
wine wineboot
- Compare
ls /tmp/.wine-$(id -u)/ against the path in the error message
The created directory is always shorter than the one Wine tries to chdir into.
Workaround
Create a dangling symlink before launching Wine. It resolves once Wine creates the short-named directory:
WINEPREFIX="${WINEPREFIX:-$HOME/.wine}"
WINE_TMP="/tmp/.wine-$(id -u)"
mkdir -p "$WINEPREFIX" "$WINE_TMP"
DEV_HEX=$(printf '%x' "$(stat -c '%d' "$WINEPREFIX")")
INO_HEX=$(printf '%x' "$(stat -c '%i' "$WINEPREFIX")")
ln -sf "$WINE_TMP/server-${DEV_HEX}-${INO_HEX}" \
"$WINE_TMP/server-${DEV_HEX}-${INO_HEX}00000000"
I freely admit to having Claude.ai's help in tracking down this issue and explaining the cause, but nevertheless think it has merit, since the workaround does sidestep it. Hopefully this gives enough information to track down where the box64 emulation is mangling the directory name.
Environment
Problem
Wine fails on startup with:
The directory that actually gets created is
server-38-53f71. The trailing00000000is not present on the created directory, but Wine expects it when it tries tochdirinto it.The values
38and53f71are thest_devandst_inoof the WINEPREFIX directory.Cause
Both wineserver and ntdll build the server directory name from the same stat values using the same format string.
server/request.c—create_server_dir()(creates the directory):dlls/ntdll/unix/server.c—server_dir_init()(looks up the directory):On native x86_64 they always match.
Under Box64,
wineservercallsasprintfthrough the native-wrapped libc path (Using native(wrapped) libc.so.6) and produces the correct short resultserver-38-53f71. Theasprintfcall insidentdll.soruns from emulated x86_64 code (Using emulated .../ntdll.so) and producesserver-38-53f7100000000— as if the upper 32 bits of theunsigned long longvariadic argument contain garbage or the argument layout is wrong.Reproduction
wine winebootls /tmp/.wine-$(id -u)/against the path in the error messageThe created directory is always shorter than the one Wine tries to chdir into.
Workaround
Create a dangling symlink before launching Wine. It resolves once Wine creates the short-named directory: