On Wed, Dec 15, 2021 at 12:18:16PM +0000, Amir Gonnen wrote: > Easier/faster synchronization is just one side of the issue. > It's much easier to debug a single process or profile it, for example. It's > also easier to deploy and maintain a single process. > > For now, the only "global state" problem I had to fix was Glib global context. > I didn't see an issue with posix signals. Any other global state you think I > should take care of?
Signal handlers are interesting because they are per-process, not per-thread. Luckily QEMU doesn't use signals that much. Accelerators like KVM use SIGUSR1 while TCG doesn't rely on signals. One example is what happens when you send SIGINT (Ctrl+C) to the process. Only one of the shared libraries will handle the signal. The other one will not be aware that SIGINT happened. The signal handlers that execute in specific threads (e.g. vCPU threads) are likely to crash or behave in weird ways. For example, softmmu/cpus.c: static void sigbus_handler(int n, siginfo_t *siginfo, void *ctx) { if (siginfo->si_code != BUS_MCEERR_AO && siginfo->si_code != BUS_MCEERR_AR) { sigbus_reraise(); } if (current_cpu) { ^^^^^^^^^^^ current_cpu is a thread-local variable. The problem is that the current_cpu symbol belongs to a specific shared library (nios2 or x86_64). If nios2 installs this signal handler then x86_64 vCPUs will not be able to handle SIGBUS because the current_cpu variable is trying to fetch the thread-local storage allocated to the other library. Global variables are also broken in the same way. If the other shared library's version of the signal handler function is executed we'll access the other global variable and not our own. Stefan
signature.asc
Description: PGP signature