<div dir="ltr"><div dir="ltr"><div dir="ltr">Thanks for your time.<div><br></div><div>FYI, I also found clone(2) from fork(3) works fine, while clone(2) from pthread_create(3) has the bug.</div><div>So, I guess the problem might be caused by thread mechanism.</div><div><br></div><div>Best,</div><div>Zhouyang</div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Nov 2, 2018 at 2:49 AM Masatake YAMATO <<a href="mailto:yamato@redhat.com">yamato@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">> Hi everyone,<br>
> <br>
> I find strace fails to trace call stack of clone syscall (called by<br>
> pthread_create) in both main thread and child thread.<br>
> <br>
> How to reproduce:<br>
> <br>
> Get a simple pthread_create example:<br>
> <a href="http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html" rel="noreferrer" target="_blank">http://www.yolinux.com/TUTORIALS/LinuxTutorialPosixThreads.html</a><br>
> Compile: gcc -pthread test_pthread.c -o test_pthread<br>
> Trace: strace -k -ff -o test_pthread ./test_pthread<br>
> <br>
> In main thread:<br>
>     clone(child_stack=0x7f56c52b1ff0,<br>
> flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID,<br>
> parent_tidptr=0x7f56c52b29d0, tls=0x7f56c52b2700,<br>
> child_tidptr=0x7f56c52b29d0) = 69700<br>
>      > /lib/x86_64-linux-gnu/<a href="http://libc-2.23.so" rel="noreferrer" target="_blank">libc-2.23.so</a>(clone+0x31) [0x1073e1]<br>
> <br>
> In child thread:<br>
>     set_robust_list(0x7f56c52b29e0, 24) = 0<br>
>      > /lib/x86_64-linux-gnu/<a href="http://libpthread-2.23.so" rel="noreferrer" target="_blank">libpthread-2.23.so</a>(start_thread+0x64) [0x7654]<br>
>      > /lib/x86_64-linux-gnu/<a href="http://libc-2.23.so" rel="noreferrer" target="_blank">libc-2.23.so</a>(clone+0x6d) [0x10741d]<br>
> <br>
> We can see the call stacks of both main thread and child thread start from<br>
> libc. Is there any way to get the call stack from the main function? I'm<br>
> not sure whether this is a bug or not.<br>
<br>
It looks a bug.<br>
<br>
About the most of all system calls, strace captures its stack trace after<br>
kernel executes the system call. However, about some system calls, caputirng<br>
after executing is not useful. I put makers "SE" on such a system call in<br>
syscallent.h. SE is defined as STACKTRACE_CAPTURE_ON_ENTER in code.<br>
I put SE markers on execve and _exit for exapmles.<br>
<br>
I should put the maker on clone, fork, and vfrok, too.<br>
Before writing this mail, I expected the bug you reported will be fixed by putting<br>
the marker on the system calls like:<br>
<br>
diff --git a/linux/x86_64/syscallent.h b/linux/x86_64/syscallent.h<br>
index 63ec52e8..2be891bd 100644<br>
--- a/linux/x86_64/syscallent.h<br>
+++ b/linux/x86_64/syscallent.h<br>
@@ -54,9 +54,9 @@<br>
 [ 53] = { 4,   TN,             SEN(socketpair),                "socketpair"            },<br>
 [ 54] = { 5,   TN,             SEN(setsockopt),                "setsockopt"            },<br>
 [ 55] = { 5,   TN,             SEN(getsockopt),                "getsockopt"            },<br>
-[ 56] = { 5,   TP,             SEN(clone),                     "clone"                 },<br>
-[ 57] = { 0,   TP,             SEN(fork),                      "fork"                  },<br>
-[ 58] = { 0,   TP,             SEN(vfork),                     "vfork"                 },<br>
+[ 56] = { 5,   TP|SE,          SEN(clone),                     "clone"                 },<br>
+[ 57] = { 0,   TP|SE,          SEN(fork),                      "fork"                  },<br>
+[ 58] = { 0,   TP|SE,          SEN(vfork),                     "vfork"                 },<br>
 [ 59] = { 3,   TF|TP|SE|SI,    SEN(execve),                    "execve"                },<br>
 [ 60] = { 1,   TP|SE,          SEN(exit),                      "exit"                  },<br>
 [ 61] = { 4,   TP,             SEN(wait4),                     "wait4"                 },<br>
<br>
<br>
However, though I put the maker on them, I cannot get expected result<br>
either using libunwind or libdw.<br>
<br>
I read the implemention of the wrapper for clone systecall.<br>
It is not written in C but in x86-64 Assembly language.<br>
So I guess the frame structure(?) that the unwinder expects are<br>
not constructed when executing clone syscall. So unwinder<br>
cannot capture a stack trace in the context.<br>
<br>
I have to take much more time for understanding the issue.<br>
<br>
Masatake YAMATO<br>
<br>
> Thanks,<br>
> Zhouyang<br>
</blockquote></div>