Hello, I think there is a little problem under gcc ! It seems that gcc thinks that a code block will never be reach and so do not generate its code, but it's wrong :
-- test.c START -- void foo_printf(char *str) { } int foo() { //assembly for sys_clone() asm volatile ( "xor %ebx, %ebx \n" "xor %ecx, %ecx \n" "xor %edx, %edx \n" "mov $120, %eax \n" "int $0x80 \n" "test %eax, %eax \n" "jnz father \n" ); asm volatile ("child:"); foo_printf("in child\n"); goto __end; asm volatile ("father:"); foo_printf("in father\n"); __end: return 0; } int main() { foo(); return 0; } -- test.c END -- Then generated assembly is this one : 00000000 <foo_printf>: 0: 55 push %ebp 1: 89 e5 mov %esp,%ebp 3: 5d pop %ebp 4: c3 ret 00000005 <foo>: 5: 55 push %ebp 6: 89 e5 mov %esp,%ebp 8: 83 ec 04 sub $0x4,%esp b: 31 db xor %ebx,%ebx d: 31 c9 xor %ecx,%ecx f: 31 d2 xor %edx,%edx 11: b8 78 00 00 00 mov $0x78,%eax 16: cd 80 int $0x80 18: 85 c0 test %eax,%eax 1a: 0f 85 fc ff ff ff jne 1c <foo+0x17> 00000020 <child>: 20: c7 04 24 00 00 00 00 movl $0x0,(%esp) 27: e8 fc ff ff ff call 28 <child+0x8> 2c: b8 00 00 00 00 mov $0x0,%eax 31: c9 leave 32: c3 ret 00000033 <main>: Father was removed because of "goto __end", simply because gcc thought that this code part will never be reached. But process is cloned() and it should have taken into account the "jnz father" The problem is the same for other conditions that make gcc think code will never be reached, like : while (1) foo_printf("in child\n"); OR foo_printf("in child\n"); return 0; Here are command line information and code generated : $ gcc -Wall -save-temps -c test.c -o test.o no warnings, but $ gcc -Wall -save-temps test.c -o test test.o: In function `foo': test.c:(.text+0x1c): undefined reference to `father' collect2: ld returned 1 exit status Ok, because label were removed from assembly ! HERE ARE GENERATED FILES : -- test.s START -- .file "test.c" .text .globl foo_printf .type foo_printf, @function foo_printf: pushl %ebp movl %esp, %ebp popl %ebp ret .size foo_printf, .-foo_printf .section .rodata .LC0: .string "in child\n" .text .globl foo .type foo, @function foo: pushl %ebp movl %esp, %ebp subl $4, %esp #APP xor %ebx, %ebx xor %ecx, %ecx xor %edx, %edx mov $120, %eax int $0x80 test %eax, %eax jnz father child: #NO_APP movl $.LC0, (%esp) call foo_printf .L3: movl $0, %eax leave ret .size foo, .-foo .globl main .type main, @function main: pushl %ebp movl %esp, %ebp subl $8, %esp andl $-16, %esp movl $0, %eax addl $15, %eax addl $15, %eax shrl $4, %eax sall $4, %eax subl %eax, %esp call foo movl $0, %eax leave ret .size main, .-main .section .note.GNU-stack,"",@progbits .ident "GCC: (GNU) 3.4.6 (Debian 3.4.6-4)" -- test.s END -- -- test.i START -- # 1 "test.c" # 1 "<built-in>" # 1 "<command line>" # 1 "test.c" void foo_printf(char *str) { } int foo() { asm volatile ( "xor %ebx, %ebx \n" "xor %ecx, %ecx \n" "xor %edx, %edx \n" "mov $120, %eax \n" "int $0x80 \n" "test %eax, %eax \n" "jnz father \n" ); asm volatile ("child:"); foo_printf("in child\n"); goto __end; asm volatile ("father:"); foo_printf("in father\n"); __end: return 0; } int main() { foo(); return 0; } -- test.i END -- -- GCC INFO -- $ gcc -v Reading specs from /usr/lib/gcc/i486-linux-gnu/3.4.6/specs Configured with: ../src/configure -v --enable-languages=c,c++,f77,pascal --prefix=/usr --libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --program-suffix=-3.4 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --with-tune=i686 i486-linux-gnu Thread model: posix gcc version 3.4.6 (Debian 3.4.6-4) $ uname -a Linux sushi 2.6.20 #7 Mon Feb 26 10:31:01 CET 2007 i686 GNU/Linux thanks stephane