Issue
I am attempting to run x86_64 playonlinux on my RPi 4B, with qemu-x86_64. I am on a 32-bit OS. Here is the error when running it:
(xenial-amd64)pi@raspberrypi44g:~/chroots/64-bit-x86 $ playonlinux
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
Looking for python... 2.7.12 - wxversion(s): 3.0-gtk2
selected
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
[main] Message: PlayOnLinux (4.2.10) is starting
[clean_tmp] Message: Cleaning temp directory
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
[Check_OpenGL] Warning: check_dd_x86 missing, test skipped
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
[Check_OpenGL] Warning: check_dd_amd64 missing, test skipped
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
[POL_System_CheckFS] Message: Checking filesystem for /home/pi/.PlayOnLinux/
[main] Message: Filesystem is compatible
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
(mainwindow.py:12318): Gdk-WARNING **: shmat failed: error 22 (Invalid argument)
/bin/bash: warning: setlocale: LC_ALL: cannot change locale (en_US.UTF-8)
/usr/share/playonlinux/playonlinux: line 126: 12318 Bus error "$POL_PYTHON" mainwindow.py "$@"
(xenial-amd64)pi@raspberrypi44g:~/chroots/64-bit-x86 $ [update_check] Message: List is up to date
[install_plugins] Message: Checking plugin: ScreenCap...
[install_plugins] Message: Checking plugin: PlayOnLinux Vault...
(xenial-amd64)pi@raspberrypi44g:~/chroots/64-bit-x86 $
What causes this error?
Solution
There are several possible causes here, but in general QEMU's user-mode emulation is far from perfect and it's probably better not to expect that it will be able to run large and complicated pieces of software, especially something like PlayOnLinux, which AFAICT is based on Wine. (The user-mode emulation is not very high on the effective priority list of the QEMU developer community, in the sense that there are not many developers who are either paid to work on that part of the code or who work on it out of personal interest, compared to other areas like system-emulation or KVM support.)
I'll start with an item zero, which is that you don't say what QEMU version you're using. If it's not the most recent version, you could try a newer QEMU and see if it helps.
First on the list of possible causes: QEMU's user-mode doesn't support 64-bit guests on 32-bit hosts. We make a best effort, which works for simple programs, but is likely to fail for more complicated ones. You could test whether this is the problem by seeing whether the program runs on a 64-on-64 combination like x86-64-on-aarch64.
Secondly, our x86-64 emulation doesn't cover more recent additions to the x86 instruction set like AVX; if the guest program assumes it can use those then it will crash or misbehave when run under QEMU. (The errors here look like they're probably not this.)
Thirdly, we might be missing or have bugs in the implementation of particular system calls or other features of the Linux ABI.
Fourthly, the x86 memory model is stricter than the Arm one, and QEMU's emulation doesn't try to compensate for this. So a multithreaded guest program might run into issues here if you're unlucky.
Tracking down which of these might be the case for this particular guest binary would require an extended debugging session where you look at what the guest is doing at the point where it fails (for instance, why does the shmat() fail? What is the immediate cause of the bus error?) and then trying to track back to what happened using a combination of the source for the guest, disassembly/reverse-engineering of the guest binary, and the source for QEMU. (If this sounds to you like it's a difficult and long process, you're not wrong :-))
Side note: the combination of "shmat fails" plus "bus error" on a graphical program makes me wonder if your setup is using a remote X session (DISPLAY set to something other than a local X server) and the guest program itself is buggy and not able to successfully fall back to a code path that doesn't use the X shared memory extension. You could test that by running the guest natively on an x86-64 host with a non-local DISPLAY setting, or by arranging to have a local X server on your Arm host.
Answered By - Peter Maydell