>> Running it in a i386 machine works and gives an output of "0x0d\n0x20". >> Running it in a qemu-i386 segfaults. Because the self-modifying code >> raises a SIGSEGV in the qemu (I understand that it is the method used by >> qemu to handle self-modifying code). But the sigprocmask disables the >> SIGSEGV and the qemu-user... does nothing to avoid it. So the SIGSEGV is >> unmanaged and breaks the program. > > Alex has the following SIGSEGV workaround queued for our openSUSE package: > http://repo.or.cz/w/qemu/agraf.git/commit/0760e24b52ff20a328f168ed23b52c9b9c0fd28f > > Don't know if it fixes your specific problem. Peter had some ideas how > to refactor signal handling but iirc didn't have time to work on it himself.
Is it similar at all? (it's easy for me to believe everyone who knows more than me about qemu internal and patches --everybody in this mailing list fits this xD). But this bug seems more subtle. I have a modified test case, maybe a bit more natural: #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <malloc.h> #include <signal.h> unsigned char *testfun; void sighandler(int signum) { printf("Hello, I'm in a signal handler\n"); mprotect(testfun, 1024, PROT_READ|PROT_EXEC|PROT_WRITE); testfun[ 1]=0x20; } int main ( void ) { unsigned int ra; signal(SIGSEGV, sighandler); testfun=memalign(getpagesize(),1024); /* // We block the SIGSEGV signal, used by qemu-user sigset_t set; sigemptyset(&set); sigaddset(&set, 11); sigprocmask(SIG_BLOCK, &set, NULL); */ mprotect(testfun, 1024, PROT_READ|PROT_EXEC|PROT_WRITE); //400687: b8 0d 00 00 00 mov $0xd,%eax //40068d: c3 retq testfun[ 0]=0xb8; testfun[ 1]=0x0d; testfun[ 2]=0x00; testfun[ 3]=0x00; testfun[ 4]=0x00; testfun[ 5]=0xc3; printf ( "0x%02X\n", ((unsigned int (*)())testfun)() ); mprotect(testfun, 1024, PROT_READ); //400687: b8 20 00 00 00 mov $0x20,%eax //40068d: c3 retq // This self-modifying code will break because of the sigsegv signal block printf ( "0x%02X\n", ((unsigned int (*)())testfun)() ); } // ------------------ This *always* goes wrong without calling the signal handler The output in usermode emulation is "0x0D\n0x0D" when it should be: --- 0x0D Hello, I'm in a signal handler 0x20 --- Alexander's patch hasn't any impact on the test case. I'm a bit lost, and not sure what is the responsible of this. But it's some kind of bug. I am eager to follow any leads and to think and generate more test cases, but (maybe) I'm failing to see some basic logic on signal flow.