Strace issue with threading
Denys Vlasenko
dvlasenk at redhat.com
Fri Jul 12 10:49:27 UTC 2013
On 07/12/2013 12:00 PM, giuseppe pes wrote:
> Hi, I have found a strange behavior using strace with an application that spawns threads. The output is printed two times and I cannot understand why.
>
> Here it is the source code of the application :
>
>
> #include <stdio.h>
> #include <sys/time.h>
> #include <stdlib.h>
> #include <errno.h>
> #include <sys/syscall.h>
> #include <sys/types.h>
> #include <sched.h>
> #include <sched.h>
> #include <linux/sched.h>
> #include <unistd.h>
> #include <sys/wait.h>
> #include <string.h>
> #include <sys/mman.h>
> #define STACK_SIZE 0x10000
> #define BUFSIZE 200
> #define _GNU_SOURCE
> void hello (void * a){
> fprintf(stdout,"Hello word hope %ld\n", syscall(SYS_gettid));
> _exit(0);
> }
>
> int main()
> {
> int res;
> void *stack = mmap(0, STACK_SIZE, PROT_READ|PROT_WRITE,
> MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
>
> printf("Stack %p\n", stack + STACK_SIZE);
> memset(stack, 0, STACK_SIZE);
> res=clone(hello,stack + STACK_SIZE, CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_FILES);
> printf("Clone result %x\n", res);
> waitpid(-1, NULL, __WALL);
> return 0;
> }
# gcc -Os -Wall t.c
t.c: In function ‘main’:
t.c:31:1: warning: passing argument 1 of ‘clone’ from incompatible pointer type [enabled by default]
res=clone(hello,stack + STACK_SIZE, CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_FILES);
^
In file included from /usr/include/sched.h:42:0,
from t.c:8:
/usr/include/bits/sched.h:82:12: note: expected ‘int (*)(void *)’ but argument is of type ‘void (*)(void *)’
extern int clone (int (*__fn) (void *__arg), void *__child_stack,
^
t.c:31:1: error: too few arguments to function ‘clone’
res=clone(hello,stack + STACK_SIZE, CLONE_SIGHAND|CLONE_FS|CLONE_VM|CLONE_FILES);
^
In file included from /usr/include/sched.h:42:0,
from t.c:8:
/usr/include/bits/sched.h:82:12: note: declared here
extern int clone (int (*__fn) (void *__arg), void *__child_stack,
^
> Here there is the output of strace -ff -o calls.txt ./clone.out
>
> Clone result 6142
> Clone result 6142
> Hello word hope 24898
>
> Stack 0x7f9bfb13f000
>
>
> The clone result should be printed just once.
It's an artifact of printf buffering.
You are using CLONE_VM, processes share their memory.
Parent's printf stores the data ("Clone result NNN") in stdout buffer,
and it gets accidentally reused by child's fprintf(stdout,...),
> 24897 write(1, "Clone result 6142\n", 18 <unfinished ...>
^^^^^^^^^
Parent
> 24898 write(1, "Clone result 6142\nHello word hop"..., 40 <unfinished ...>
^^^^^^^^^^^
Child uses parent's buffered data
If you replace [f]printf's with "dprintf(1, ...)" it stops happening.
--
vda
More information about the Strace-devel
mailing list