[BZ,#18508] S390: Fix "backtrace() returns infinitely deep stack frames with makecontext()".
Commit Message
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.
Comments
On 06/09/2015 05:42 PM, Stefan Liebler wrote:
> 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?)"
Is it possible to extract a test case from the Go program, by calling
makecontext and backtrace in the same way to Go run time does?
I think this would be a useful addition to the glibc test suite.
@@ -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. */
@@ -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. */