strace bug for clone()

Michael Holzheu HOLZHEU at de.ibm.com
Thu Feb 26 06:44:33 UTC 2004





Hi all,

The clone() system call is not handled correctly in strace for s390(x)
under Linux.

The following testprogram under linux 2.6 fails:

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <sched.h>
#include <signal.h>

char stack[10000];

int childfn(void* arg)
{
        printf("CHILD\n");
        return 0;
}

int main(void)
{
        pid_t child;
        int status,rc;
        child = clone(&childfn,stack+sizeof(stack)
,CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD ,NULL);
        rc = waitpid(child,&status,0);
        printf("parent rc: %i\n",rc);
        return 0;
}


>>> strace -f ./test
....
clone(Process 15636 attached
child_stack=0x403fec,
flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0) =
15636
[pid 15635] --- SIGCHLD (Child exited) @ 0 (0) ---
[pid 15635] wait4(15636, Process 15635 suspended

<strace hangs here>


The problem is that on s390 the paramters of clone() are ordered in a
different way than on all other platforms. When tracing the clone() system
call the argument 0 (the flags argument which is argument 1 on s390) is
or'd with CLONE_PTRACE and is written back. Because on s390 the arguments
are swapped, we overwrite the old clone flags here.

Here is a fix for the problem:

--- util.c.orig   2004-02-25 16:26:10.268979783 +0100
+++ util.c  2004-02-26 15:01:25.048979783 +0100
@@ -1230,14 +1230,8 @@
 #else

 # if defined S390 || defined S390X
-/* Note: this is only true for the `clone' system call, which handles
-   arguments specially.  We could as well say that its first two arguments
-   are swapped relative to other architectures, but that would just be
-   another #ifdef in the calls.  */
-#  define arg0_offset  PT_GPR3
-#  define arg1_offset  PT_ORIGGPR2
-#  define restore_arg0(tcp, state, val) ((void) (state), 0)
-#  define restore_arg1(tcp, state, val) ((void) (state), 0)
+#  define arg0_offset  PT_ORIGGPR2
+#  define arg1_offset  PT_GPR3
 # elif defined (ALPHA) || defined (MIPS)
 #  define arg0_offset  REG_A0
 #  define arg1_offset  (REG_A0+1)
@@ -1317,6 +1311,21 @@
      case SYS_fork:
 #endif
 #if defined SYS_fork || defined SYS_vfork
+#if defined(S390) || defined(S390X)
+/* Note: On s390(x) the `clone' system call arguments are arranged
differnt
+         then on other architectures
+*/
+           if (arg_setup (tcp, &state) < 0
+               || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
+               || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
+               || change_syscall(tcp, SYS_clone) < 0
+               || set_arg1 (tcp, &state, CLONE_PTRACE|SIGCHLD) < 0
+               || set_arg0 (tcp, &state, 0) < 0
+               || arg_finish_change (tcp, &state) < 0)
+                 return -1;
+           tcp->u_arg[0] = 0;
+           tcp->u_arg[1] = CLONE_PTRACE|SIGCHLD;
+#else
            if (arg_setup (tcp, &state) < 0
                || get_arg0 (tcp, &state, &tcp->inst[0]) < 0
                || get_arg1 (tcp, &state, &tcp->inst[1]) < 0
@@ -1327,6 +1336,7 @@
                  return -1;
            tcp->u_arg[0] = CLONE_PTRACE|SIGCHLD;
            tcp->u_arg[1] = 0;
+#endif
            tcp->flags |= TCB_BPTSET;
            return 0;
 #endif
@@ -1335,11 +1345,19 @@
 #ifdef SYS_clone2
      case SYS_clone2:
 #endif
+#if defined(S390) || defined(S390X)
+           if ((tcp->u_arg[1] & CLONE_PTRACE) == 0
+               && (arg_setup (tcp, &state) < 0
+                 || set_arg1 (tcp, &state, tcp->u_arg[1] | CLONE_PTRACE) <
0
+                 || arg_finish_change (tcp, &state) < 0))
+                 return -1;
+#else
            if ((tcp->u_arg[0] & CLONE_PTRACE) == 0
                && (arg_setup (tcp, &state) < 0
                  || set_arg0 (tcp, &state, tcp->u_arg[0] | CLONE_PTRACE) <
0
                  || arg_finish_change (tcp, &state) < 0))
                  return -1;
+#endif
            tcp->flags |= TCB_BPTSET;
            tcp->inst[0] = tcp->u_arg[0];
            tcp->inst[1] = tcp->u_arg[1];


(See attached file: strace-4.5.1-clone.diff)

Best Regards

       Michael

------------------------------------------------------------------------
Linux for E-Server Development
Phone: +49-7031-16-2360,  Bld 71032-03-U09
Email: holzheu at de.ibm.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: strace-4.5.1-clone.diff
Type: application/octet-stream
Size: 2372 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20040226/bb9cde89/attachment.obj>


More information about the Strace-devel mailing list