Today I tried testing interrupted systemcalls on UML 2.6.8.1-1 with the incremental patches up to skas-flush-tlb. My host does not yet support the new SYSEMU-ptrace.

In skas-mode, the uml system with this kernel doesn’t boot! It panics with the message:

 

Kernel panic: handle_trap - failed to wait at end of syscall, errno = 4, status = 4479

 

Tracking this down I saw that “errno = 4” from the message is misleading! It’s an old errno, the return value of waitpid() is the pid of the user-thread. It seems to be stopped by SIGCHLD.

I do not understand exactly what happens, but the signal seems to be generated while running handle_syscall() called from handle_trap(). Changing back to the sequence of calling waitpid() and handle_syscall() as it has been before the sysemu-patch removed the problem.

 

Here is my patch (I also changed the panic message to include “err” and to print status in Hex):

 

Bodo

 

 

--- tmp/linux-2.6.8.1/arch/um/kernel/skas/process.c     2004-09-17 19:20:15.000000000 +0200

+++ linux-2.6.8.1/arch/um/kernel/skas/process.c 2004-09-20 21:31:39.451946258 +0200

@@ -68,25 +68,25 @@

                return;

        }

 

-       handle_syscall(regs);

-       if(use_sysemu)

-               return;

+       if(!use_sysemu) {

+               err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);

+               if(err < 0)

+                       panic("handle_trap - nullifying syscall failed, errno = %d\n",

+                             errno);

 

-       err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);

-       if(err < 0)

-               panic("handle_trap - nullifying syscall failed, errno = %d\n",

-                     errno);

+               err = ptrace(PTRACE_SYSCALL, pid, 0, 0);

+               if(err < 0)

+                       panic("handle_trap - continuing to end of syscall failed, "

+                             "errno = %d\n", errno);

 

-       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);

-       if(err < 0)

-               panic("handle_trap - continuing to end of syscall failed, "

-                     "errno = %d\n", errno);

-

-       CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));

-       if((err < 0) || !WIFSTOPPED(status) ||

-          (WSTOPSIG(status) != SIGTRAP))

-               panic("handle_trap - failed to wait at end of syscall, "

-                     "errno = %d, status = %d\n", errno, status);

+               CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));

+               if((err < 0) || !WIFSTOPPED(status) ||

+                  (WSTOPSIG(status) != SIGTRAP))

+                       panic("handle_trap - failed to wait at end of syscall, "

+                             "err = %d, errno = %d, status = %x\n", err, errno, status);

+       }

+

+       handle_syscall(regs);

 }