If a program is traced or debugged, in 2.6.x interrupted systemcalls with the results –ERESTARTxxxxxxx are not handled correctly, do systemcall restart is done.

Here is a patch that should fix the problem. The patch is tested on 2.6.6 in tt and skas modes. It applies to 2.6.8.1, but I’ve not tested yet.

Hope, this helps.

 

Bodo

 

 

 

 

--- uml_orig/arch/um/kernel/signal_kern.c 2004-08-05 18:36:24.000000000 +0200

+++ uml/arch/um/kernel/signal_kern.c      2004-09-17 15:03:30.441065600 +0200

@@ -132,19 +132,18 @@

 {

      siginfo_t info;

      struct k_sigaction *ka;

-     int err, sig;

+     int sig;

 

      if (!oldset)

            oldset = &current->blocked;

 

      sig = get_signal_to_deliver(&info, regs, NULL);

-     if(sig == 0)

-           return(0);

-

-     /* Whee!  Actually deliver the signal.  */

-     ka = &current->sighand->action[sig -1 ];

-     err = handle_signal(regs, sig, ka, &info, oldset, error);

-     if(!err) return(1);

+     if(sig > 0) {

+           /* Whee!  Actually deliver the signal.  */

+           ka = &current->sighand->action[sig -1 ];

+           handle_signal(regs, sig, ka, &info, oldset, error);

+           return(1);

+     }

 

      /* Did we come from a system call? */

      if(PT_REGS_SYSCALL_NR(regs) >= 0){

--- uml_orig/arch/um/kernel/skas/process.c      2004-08-05 18:36:24.000000000 +0200

+++ uml/arch/um/kernel/skas/process.c     2004-09-17 17:35:09.236250499 +0200

@@ -63,7 +63,7 @@

 

      syscall_nr = PT_SYSCALL_NR(regs->skas.regs);

      UPT_SYSCALL_NR(regs) = syscall_nr;

-     if(syscall_nr < 1){

+     if(syscall_nr < 0){

            relay_signal(SIGTRAP, regs);

            return;

      }

--- uml_orig/arch/um/kernel/skas/syscall_user.c 2004-08-05 18:36:24.000000000 +0200

+++ uml/arch/um/kernel/skas/syscall_user.c      2004-09-17 18:52:50.655271683 +0200

@@ -10,10 +10,6 @@

 #include "sysdep/ptrace.h"

 #include "sysdep/sigcontext.h"

 

-/* XXX Bogus */

-#define ERESTARTSYS    512

-#define ERESTARTNOINTR 513

-#define ERESTARTNOHAND 514

 

 void handle_syscall(union uml_pt_regs *regs)

 {

@@ -26,9 +22,6 @@

      result = execute_syscall(regs);

 

      REGS_SET_SYSCALL_RETURN(regs->skas.regs, result);

-     if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||

-        (result == -ERESTARTNOINTR))

-           do_signal(result);

 

      syscall_trace(regs, 0);

      record_syscall_end(index, result);

--- uml_orig/arch/um/kernel/tt/syscall_user.c   2004-08-05 18:36:24.000000000 +0200

+++ uml/arch/um/kernel/tt/syscall_user.c  2004-09-17 18:52:41.978671390 +0200

@@ -17,10 +17,6 @@

 #include "syscall_user.h"

 #include "tt.h"

 

-/* XXX Bogus */

-#define ERESTARTSYS    512

-#define ERESTARTNOINTR 513

-#define ERESTARTNOHAND 514

 

 void syscall_handler_tt(int sig, union uml_pt_regs *regs)

 {

@@ -42,9 +38,6 @@

      UPT_SC(regs) = sc;

 

      SC_SET_SYSCALL_RETURN(sc, result);

-     if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) ||

-        (result == -ERESTARTNOINTR))

-           do_signal(result);

 

      syscall_trace(regs, 0);

      record_syscall_end(index, result);

@@ -63,7 +56,7 @@

      regs = TASK_REGS(task);

      UPT_SYSCALL_NR(regs) = syscall;

 

-     if(syscall < 1) return(0);

+     if(syscall < 0) return(0);

 

      if((syscall != __NR_sigreturn) &&

         ((unsigned long *) PT_IP(proc_regs) >= &_stext) &&