Hi,

this testcase hangs on ia64:

$ echo 'int main () { return vfork (); }' >vfork.c; gcc -o vfork vfork.c; 
strace -f ./vfork
execve("./vfork", ["./vfork"], [/* 41 vars */]) = 1
...
clone(Process 2929 attached (waiting for parent)

Fix tested on RHEL-5 kernel-2.6.18-94.el5.ia64.  Older kernels (such as
kernel-2.6.18-53.el5.ia64) do not hang as they have a bug causing strace not
tracing the children (as strace is unable to force CLONE_PTRACE there).
Sorry for no ia64 vanilla kernels testing.


Regards,
Jan
2008-06-27  Jan Kratochvil  <[EMAIL PROTECTED]>

        * util.c (CLONE_VFORK): Define if not defined already.
        (setbpt): Clear CLONE_VFORK for SYS_CLONE and SYS_CLONE2.  New comment.
        Originally found by Vitaly Mayatskikh.

--- util.c      20 May 2008 00:34:34 -0000      1.75
+++ util.c      30 Jun 2008 12:53:31 -0000
@@ -1281,6 +1281,9 @@ struct tcb *tcp;
 #ifndef CLONE_PTRACE
 # define CLONE_PTRACE    0x00002000
 #endif
+#ifndef CLONE_VFORK
+# define CLONE_VFORK     0x00004000
+#endif
 #ifndef CLONE_STOPPED
 # define CLONE_STOPPED   0x02000000
 #endif
@@ -1524,12 +1527,17 @@ struct tcb *tcp;
 #ifdef SYS_clone2
        case SYS_clone2:
 #endif
-               if ((tcp->u_arg[arg0_index] & CLONE_PTRACE) == 0
-                   && (arg_setup (tcp, &state) < 0
-                       || set_arg0 (tcp, &state,
-                                    tcp->u_arg[arg0_index] | CLONE_PTRACE) < 0
-                       || arg_finish_change (tcp, &state) < 0))
-                       return -1;
+               /* ia64 calls directly `clone (CLONE_VFORK)' contrary to x86
+                  SYS_vfork above.  Even on x86 we turn the VFORK semantics
+                  into plain FORK - each application must not depend on the
+                  VFORK specifics according to POSIX.  We would hang waiting
+                  for the parent resume otherwise.  */
+               if ((arg_setup (tcp, &state) < 0
+                   || set_arg0 (tcp, &state,
+                                (tcp->u_arg[arg0_index] | CLONE_PTRACE)
+                                & ~CLONE_VFORK) < 0
+                   || arg_finish_change (tcp, &state) < 0))
+                   return -1;
                tcp->flags |= TCB_BPTSET;
                tcp->inst[0] = tcp->u_arg[arg0_index];
                tcp->inst[1] = tcp->u_arg[arg1_index];
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://sourceforge.net/services/buy/index.php
_______________________________________________
Strace-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to