It seems there is a bug in SIGALRM handling when 486 system emulates x86_64 code.
This code: #include <stdio.h> #include <stdlib.h> #include <pthread.h> #include <signal.h> #include <unistd.h> pthread_t thread1, thread2; // Signal handler for SIGALRM void alarm_handler(int sig) { // Do nothing, just wake up the other thread } // Thread 1 function void* thread1_func(void* arg) { // Set up the signal handler for SIGALRM signal(SIGALRM, alarm_handler); // Wait for 5 seconds sleep(1); // Send SIGALRM signal to thread 2 pthread_kill(thread2, SIGALRM); return NULL; } // Thread 2 function void* thread2_func(void* arg) { // Wait for the SIGALRM signal pause(); printf("Thread 2 woke up!\n"); return NULL; } int main() { // Create thread 1 if (pthread_create(&thread1, NULL, thread1_func, NULL) != 0) { fprintf(stderr, "Failed to create thread 1\n"); return 1; } // Create thread 2 if (pthread_create(&thread2, NULL, thread2_func, NULL) != 0) { fprintf(stderr, "Failed to create thread 2\n"); return 1; } // Wait for both threads to finish pthread_join(thread1, NULL); pthread_join(thread2, NULL); return 0; } Fails with this -strace log (there are also unsupported syscalls 334 and 435, but it seems it doesn't affect the code much): ... 736 rt_sigaction(SIGALRM,0x000000001123ec20,0x000000001123ecc0) = 0 736 clock_nanosleep(CLOCK_REALTIME,0,{tv_sec = 1,tv_nsec = 0},{tv_sec = 1,tv_nsec = 0}) 736 rt_sigprocmask(SIG_BLOCK,0x00000000109fad20,0x0000000010800b38,8) = 0 736 Unknown syscall 435 736 clone(CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID| ... 736 rt_sigprocmask(SIG_SETMASK,0x0000000010800b38,NULL,8) 736 set_robust_list(0x11a419a0,0) = -1 errno=38 (Function not implemented) 736 rt_sigprocmask(SIG_SETMASK,0x0000000011a41fb0,NULL,8) = 0 = 0 736 pause(0,0,2,277186368,0,295966400) 736 futex(0x000000001123f990,FUTEX_CLOCK_REALTIME|FUTEX_WAIT_BITSET,738,NULL,NULL,0) = 0 736 rt_sigprocmask(SIG_BLOCK,0x00000000109fad20,0x000000001123ee88,8) = 0 736 getpid() = 736 736 tgkill(736,739,SIGALRM) = 0 = -1 errno=4 (Interrupted system call) --- SIGALRM {si_signo=SIGALRM, si_code=SI_TKILL, si_pid=736, si_uid=0} --- 0x48874a != 0x3c69e10 736 rt_sigprocmask(SIG_SETMASK,0x000000001123ee88,NULL,8) = 0 ** ERROR:../accel/tcg/cpu-exec.c:546:cpu_exec_longjmp_cleanup: assertion failed: (cpu == current_cpu) Bail out! ERROR:../accel/tcg/cpu-exec.c:546:cpu_exec_longjmp_cleanup: assertion failed: (cpu == current_cpu) 0x48874a != 0x3c69e10 ** ERROR:../accel/tcg/cpu-exec.c:546:cpu_exec_longjmp_cleanup: assertion failed: (cpu == current_cpu) Bail out! ERROR:../accel/tcg/cpu-exec.c:546:cpu_exec_longjmp_cleanup: assertion failed: (cpu == current_cpu) # The code fails either with or without -singlestep, the command line: /usr/bin/qemu-x86_64 -L /opt/x86_64 -strace -singlestep /opt/x86_64/alarm.bin Source code of QEMU 8.1.1 was modified with patch "[PATCH] qemu/timer: Don't use RDTSC on i486" [1], with added few ioctls (not relevant) and cpu_exec_longjmp_cleanup() now prints current pointers of cpu and current_cpu (line "0x48874a != 0x3c69e10"). config.log (built as a part of buildroot, basically the minimal possible configuration for running x86_64 on 486): # Configured with: '/mnt/hd_8tb_p1/p1/home/crossgen/buildroot_486_2/output/build/qemu-8.1.1/configure' '--prefix=/usr' '--cross-prefix=/mnt/hd_8tb_p1/p1/home/crossgen/buildroot_486_2/output/host/bin/i486-buildroot-linux-gnu-' '--audio-drv-list=' '--python=/mnt/hd_8tb_p1/p1/home/crossgen/buildroot_486_2/output/host/bin/python3' '--ninja=/mnt/hd_8tb_p1/p1/home/crossgen/buildroot_486_2/output/host/bin/ninja' '--disable-alsa' '--disable-bpf' '--disable-brlapi' '--disable-bsd-user' '--disable-cap-ng' '--disable-capstone' '--disable-containers' '--disable-coreaudio' '--disable-curl' '--disable-curses' '--disable-dbus-display' '--disable-docs' '--disable-dsound' '--disable-hvf' '--disable-jack' '--disable-libiscsi' '--disable-linux-aio' '--disable-linux-io-uring' '--disable-malloc-trim' '--disable-membarrier' '--disable-mpath' '--disable-netmap' '--disable-opengl' '--disable-oss' '--disable-pa' '--disable-rbd' '--disable-sanitizers' '--disable-selinux' '--disable-sparse' '--disable-strip' '--disable-vde' '--disable-vhost-crypto' '--disable-vhost-user-blk-server' '--disable-virtfs' '--disable-whpx' '--disable-xen' '--disable-attr' '--disable-kvm' '--disable-vhost-net' '--disable-download' '--disable-hexagon-idef-parser' '--disable-system' '--enable-linux-user' '--target-list=x86_64-linux-user' '--disable-vhost-user' '--disable-slirp' '--disable-sdl' '--disable-fdt' '--enable-trace-backends=nop' '--disable-tools' '--disable-guest-agent' '--disable-fuse' '--disable-fuse-lseek' '--disable-seccomp' '--disable-libssh' '--disable-libusb' '--disable-vnc' '--disable-nettle' '--disable-numa' '--disable-pipewire' '--disable-spice' '--disable-usb-redir' '--disable-install-blobs' Emulation of the same x86_64 code with qemu 6.2.0 installed on another x86_64 native machine works fine. [1] https://lists.nongnu.org/archive/html/qemu-devel/2023-11/msg05387.html Best regards, Petr