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

Attachment: signature.asc
Description: PGP signature

Reply via email to