This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
[PATCH][BZ #18508] S390: Fix "backtrace() returns infinitely deep stack frames with makecontext()".
- From: Stefan Liebler <stli at linux dot vnet dot ibm dot com>
- To: libc-alpha at sourceware dot org
- Date: Tue, 09 Jun 2015 17:42:22 +0200
- Subject: [PATCH][BZ #18508] S390: Fix "backtrace() returns infinitely deep stack frames with makecontext()".
- Authentication-results: sourceware.org; auth=none
Hi,
On s390/s390x backtrace(buffer, size) returns the series of called
functions until "makecontext_ret" and additional entries (up to "size")
with "makecontext_ret".
GDB-backtrace is also warning: "Backtrace stopped: previous frame
identical to this frame (corrupt stack?)"
To reproduce this scenario you have to setup a new context with
makecontext() and activate it with setcontext(). See e.g. cf() function
in testcase stdlib/tst-makecontext.c.
Or see bug in libgo "Bug 66303 - runtime.Caller() returns infinitely
deep stack frames on s390x "
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66303).
This patch omits the cfi_startproc/cfi_endproc directives in ENTRY/END
macro of __makecontext_ret. Thus no frame information is generated in
.eh_frame and backtrace stops after __makecontext_ret. There is also no
.eh_frame info for _start or thread_start functions.
Ok to commit?
Bye
Stefan
---
2015-06-09 Stefan Liebler <stli@linux.vnet.ibm.com>
[BZ #18508]
* sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
(__makecontext_ret): Omit cfi_startproc and cfi_endproc.
* sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S:
Likewise.
diff --git a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
index e1f9347..8d36ea2 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-32/__makecontext_ret.S
@@ -17,6 +17,14 @@
#include <sysdep.h>
+/* We do not want .eh_frame info for __makecontext_ret to stop unwinding
+ if backtrace() was called within a context created by makecontext.
+ (there is also no .eh_frame info for _start or thread_start) */
+#undef cfi_startproc
+#define cfi_startproc
+#undef cfi_endproc
+#define cfi_endproc
+
ENTRY(__makecontext_ret)
basr %r14,%r7
ltr %r8,%r8 /* Check whether uc_link is 0. */
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
index 11a3cd3..64619f1 100644
--- a/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
+++ b/sysdeps/unix/sysv/linux/s390/s390-64/__makecontext_ret.S
@@ -17,6 +17,14 @@
#include <sysdep.h>
+/* We do not want .eh_frame info for __makecontext_ret to stop unwinding
+ if backtrace() was called within a context created by makecontext.
+ (there is also no .eh_frame info for _start or thread_start) */
+#undef cfi_startproc
+#define cfi_startproc
+#undef cfi_endproc
+#define cfi_endproc
+
ENTRY(__makecontext_ret)
basr %r14,%r7
ltgr %r8,%r8 /* Check whether uc_link is 0. */