Re: mutex syscall patch, questions about clone and its possible bugs

Jakub Jelinek (jj@sunsite.ms.mff.cuni.cz)
Sun, 12 May 1996 17:51:41 +0200 (MET DST)


I wrote in my last mail:
> My second question is: has anyone tried the clone system call? Was it
> working? My experience (I'm testing on 1.3.98/i486) is that if clone is called
> without the CLONE_VM flag, then everything goes ok (just if I set the new
> stack somewhere, both the parent and child use the old stack - a simple test
> programs tells me that before clone(CLONE_FILES|CLONE_FS|SIGCHLD,40000000)
> the stack is somewhere at BFFFFD20 and after in both parent and child it is
> similar), but if I call clone(CLONE_VM|CLONE_FILES|CLONE_FS|SIGCHLD,40000000)
> (- 40000000 is a return value from malloc, in fact some digits are not
> zeroes), the child SIGSEGV faults before doing anything. And of course, core
> doesn't show anything interesting. I've looked at the i386 port and saw that
> the esp in pt_regs is set up correctly, but then in RESTORE_ALL you just
> call iret and don't change esp and copy the 16 or whatever bytes from the
> old to the new stack. Am I right with this? Can this be fixed? I don't thing
> restoring of esp in RESTORE_ALL would be a good idea, what about calling a
> special RESTORE_CLONE_ALL on return from the sys_call routine?
Sorry, this was my fault. Just haven't looked at libc very well. I had to
write an assembler function around the syscall, so that it works well. No it
works well, if after calling clone in the 0 case (child) I immediately call
some function which never exits (so that no segfaults happen because of
stack fault). If anyone's interested, here's the clone.S code (would be
happy if this could go to libc):

.file "clone.S"

#include <sysdeps/linux/i386/sysdep.h>
#include <sys/syscall.h>

.text;
#if defined(__PIC__) || defined (__pic__)

.text;
ENTRY (clone)
pushl %ebp;
movl %esp,%ebp;
PUSH_5
MOVE_2
movl $SYS_clone,%eax
orl %ecx,%ecx
jne .L__clone_stack
int $0x80;
.L__clone_after_syscall:
movl %eax,%edx;
test %edx,%edx;
jge L(Lexit);
negl %edx;
pushl %edx;
call L(L4);
LL(L4)
popl %ebx;
addl $_GLOBAL_OFFSET_TABLE_+[.-L(L4)],%ebx;
call ERRNO_LOCATION@PLT;
popl %edx;
movl %edx,(%eax);
movl $-1,%eax;
LL(Lexit)
POP_5
movl %ebp,%esp;
popl %ebp;

#else /* PIC */

.text;
ENTRY (clone)
pushl %ebp;
movl %esp,%ebp;
PUSH_5
MOVE_2
movl $SYS_clone,%eax
orl %ecx,%ecx
jne .L__clone_stack
int $0x80;
.L__clone_after_syscall:
movl %eax,%edx;
test %edx,%edx;
jge L(Lexit);
negl %edx;
pushl %edx;
call ERRNO_LOCATION;
popl %edx;
movl %edx,(%eax);
movl $-1,%eax;
LL(Lexit)
POP_5
movl %ebp,%esp;
popl %ebp;

#endif /* PIC */
ret
.L__clone_stack:
subl $32,%ecx
movl %esp,%esi
movl %ecx,%edi
movl $8,%ecx
cld
rep
movsl
MOVE_5
subl $32,%ecx
int $0x80
movl %esp,%ebp
addl $12,%ebp
jmp .L__clone_after_syscall

#ifdef __ELF__
.type clone,@function
.L_clone_end:
.size clone,.L_clone_end - clone
#endif

+---------------------------------------------------------------------------+
| Jakub Jelinek http://sunsite.mff.cuni.cz/~jj |
| Administrator of SunSITE Czech Republic jj@sunsite.mff.cuni.cz |
| Na Orechovce 7, 162 00 Praha 6, Czech Republic jj@gnu.ai.mit.edu |
| School: MFF UK, Praha; Work: MFF UK & VC CVUT, Praha jj@jfch.vc.cvut.cz |
+---------------------------------------------------------------------------+