[BZ,#18508] S390: Fix "backtrace() returns infinitely deep stack frames with makecontext()".

Message ID ml71gu$et2$1@ger.gmane.org
State Superseded
Headers

Commit Message

Stefan Liebler June 9, 2015, 3:42 p.m. UTC
  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

Florian Weimer June 12, 2015, 9:14 a.m. UTC | #1
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.
  

Patch

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.  */