From c8ad49f04fbf237964e2c8243bfd5ec5ccee7331 Mon Sep 17 00:00:00 2001
From: Georgiy Lebedev <g.lebedev@tarantool.org>
Date: Mon, 7 Mar 2022 14:41:42 +0300
Subject: [PATCH] core: fix `coro_unwcontext` invalid unwind info
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

During the context switch required for backtracing a suspended fiber,
unwinders go crazy, as the unwind information they had gets implicitly
invalidated: provide an annotation for a dummy frame for
`coro_unwcontext`, as if it were at the bottom of the call-chain — that
way unwinders can normally proceed further.

We need to know the exact location of the stack pointer: replace the
16-byte stack alignment instruction on x86_64 macOS by adding the
`force_align_arg_pointer` attribute to `unw_getcontext_f`.

Needed for #4002

NO_DOC=bug fix
NO_CHANGELOG=bug fix
NO_TEST=unwind information annotation in inline assembly
---
 src/lib/core/backtrace.cc | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/src/lib/core/backtrace.cc b/src/lib/core/backtrace.cc
index c1f1d71273..3f1d5c0e1e 100644
--- a/src/lib/core/backtrace.cc
+++ b/src/lib/core/backtrace.cc
@@ -196,6 +196,9 @@ backtrace(char *start, size_t size)
  * @param stack pointer to preserve.
  * @retval preserved stack pointer.
  */
+#ifdef __x86_64__
+__attribute__ ((__force_align_arg_pointer__))
+#endif /* __x86_64__ */
 static void *
 unw_getcontext_f(unw_context_t *unw_context, void *stack)
 {
@@ -246,11 +249,11 @@ __asm__ volatile(
 	"\tmovq 40(%%rsp), %%rbp\n"
 	/* Set first arg and call */
 	"\tmovq %0, %%rdi\n"
-#ifdef TARGET_OS_DARWIN
-	"\tandq $0xfffffffffffffff0, %%rsp\n"
-#endif
+	".cfi_remember_state\n"
+	".cfi_def_cfa %%rsp, 8 * 7\n"
 	"\tleaq %P2(%%rip), %%rax\n"
 	"\tcall *%%rax\n"
+	".cfi_restore_state\n"
 	/* Restore old sp and context */
 	"\tmov %%rax, %%rsp\n"
 	"\tpopq %%r15\n"
@@ -354,7 +357,12 @@ __asm__ volatile(
 	"\tmov sp, x2\n"
 	/* Setup fisrst arg */
 	"\tmov x0, %0\n"
+	".cfi_remember_state\n"
+	".cfi_def_cfa sp, 8 * 20\n"
+	".cfi_offset x29, -16 * 5\n"
+	".cfi_offset x30, -16 * 5 + 8\n"
 	"\tbl %2\n"
+	".cfi_restore_state\n"
 	/* Restore context (old sp in x0) */
 	"\tldp x19, x20, [x0, #16 * 0]\n"
 	"\tldp x21, x22, [x0, #16 * 1]\n"
-- 
GitLab