diff --git a/cmake/BuildLibCORO.cmake b/cmake/BuildLibCORO.cmake
index 3a9c95426a1fd75b0bb00a04ccdcc593b7932f30..860aabd5e3b50117cb93855aced943373f295a60 100644
--- a/cmake/BuildLibCORO.cmake
+++ b/cmake/BuildLibCORO.cmake
@@ -4,6 +4,8 @@ macro(libcoro_build)
     set(coro_src
         ${PROJECT_SOURCE_DIR}/third_party/coro/coro.c
     )
+    set_source_files_properties(${coro_src} PROPERTIES
+                                COMPILE_FLAGS -fomit-frame-pointer)
 
     add_library(coro STATIC ${coro_src})
 
@@ -20,4 +22,3 @@ macro(libcoro_build)
 
     unset(coro_src)
 endmacro(libcoro_build)
-
diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake
index c0b3b4703a2e5819c7b857baf5ad6e1fffa6bc1b..fb1a70fa0d9b7b83655dd0bdf43ce60b99d16b1b 100644
--- a/cmake/compiler.cmake
+++ b/cmake/compiler.cmake
@@ -179,17 +179,6 @@ endif()
 
 add_compile_flags("C;CXX" "-fexceptions" "-funwind-tables")
 
-# We must set -fno-omit-frame-pointer here, since we rely
-# on frame pointer when getting a backtrace, and it must
-# be used consistently across all object files.
-# The same reasoning applies to -fno-stack-protector switch.
-
-if (ENABLE_BACKTRACE)
-    add_compile_flags("C;CXX"
-        "-fno-omit-frame-pointer"
-        "-fno-stack-protector")
-endif()
-
 # In C a global variable without a storage specifier (static/extern) and
 # without an initialiser is called a ’tentative definition’. The
 # language permits multiple tentative definitions in the single
diff --git a/third_party/coro/coro.c b/third_party/coro/coro.c
index ca490dc268a9d8816bf4165dfcea3765e05aca11..5028e3c1466fecfa2b46b64c7e93db7a76290b25 100644
--- a/third_party/coro/coro.c
+++ b/third_party/coro/coro.c
@@ -40,6 +40,8 @@
 
 #include "coro.h"
 
+#include "trivia/config.h"
+
 #include <stddef.h>
 #include <string.h>
 
@@ -103,13 +105,36 @@ coro_init (void)
 
   coro_transfer (new_coro, create_coro);
 
-#if __GCC_HAVE_DWARF2_CFI_ASM && __amd64
-  asm (".cfi_undefined rip");
-#endif
-
-  func ((void *)arg);
-
-  /* the new coro returned. bad. just abort() for now */
+  __asm__ volatile(
+#ifdef ENABLE_BACKTRACE
+  /*
+   * Call-chain ends here: we need to invalidate this frame's return
+   * address to make unwinding stop here.
+   */
+
+   /* Clearing rbp is insufficient: undefine rip value's location — see: https://github.com/libunwind/libunwind/blob/ec171c9ba7ea3abb2a1383cee2988a7abd483a1f/src/x86_64/Gstep.c#L91-L92 */
+  ".cfi_undefined rip\n"
+  /* Undefine rbp value's location — ibid. */
+  ".cfi_undefined rbp\n"
+  /* Undefine rbp-relative return address location, see: https://github.com/libunwind/libunwind/blob/ec171c9ba7ea3abb2a1383cee2988a7abd483a1f/src/dwarf/Gparser.c#L877 */
+  ".cfi_return_column rbp\n"
+#endif /* ENABLE_BACKTRACE */
+  /* Clear rbp to conform to the x86_64 ABI, see: https://github.com/libunwind/libunwind/blob/ec171c9ba7ea3abb2a1383cee2988a7abd483a1f/src/x86_64/Gstep.c#L144-L148 */
+  "\txorq %%rbp, %%rbp\n"
+  "\tmovq %0, %%rdi\n"
+  "\tcallq *%1\n"
+  :
+  : "rm" (arg), "rm" (func), "m" (*arg)
+  : "rbp", "rax", "rcx", "rdx", "rsi", "rdi", "r8", "r9", "r10", "r11",
+    "xmm0","xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7",
+    "xmm8","xmm9", "xmm10", "xmm11", "xmm12", "xmm13", "xmm14", "xmm15",
+#ifdef __AVX512F__
+    "xmm16", "xmm17", "xmm18", "xmm19", "xmm20", "xmm21", "xmm22",
+    "xmm23", "xmm24", "xmm25", "xmm26", "xmm27", "xmm28", "xmm29",
+    "xmm30", "xmm31", "k0", "k1", "k2", "k3", "k4", "k5", "k6", "k7",
+#endif /* __AVX512F__ */
+    "mm0","mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm6", "st",
+    "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)");
   abort ();
 }
 # endif
@@ -320,13 +345,21 @@ trampoline (int sig)
          ".fnend\n"
 
        #elif __aarch64__
-
+#ifdef ENABLE_BACKTRACE
          ".cfi_startproc\n"
-         "\tmov x30, #0\n"
-         "\tsub sp, sp, #16\n"
-         "\tstr x30, [sp, #0]\n"
-         ".cfi_def_cfa_offset 16\n"
-         ".cfi_offset 30, -16\n"
+         /*
+          * Call-chain ends here: we need to invalidate this frame's return
+          * address to make unwinding stop here.
+          */
+
+         /*
+          * Detection of call-chain end on AARCH64 ABI inherently relies on CFI,
+          * see: https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#623the-frame-pointer.
+          * Simply undefine x29 and x30 register values' locations.
+          */
+         ".cfi_undefined x29\n"
+         ".cfi_undefined x30\n"
+#endif /* ENABLE_BACKTRACE */
          "\tmov x0, x20\n"
          "\tblr x19\n"
 # ifdef __APPLE__
@@ -334,8 +367,9 @@ trampoline (int sig)
 # else
          "\tb abort\n"
 # endif
+#ifdef ENABLE_BACKTRACE
          ".cfi_endproc\n"
-
+#endif /* ENABLE_BACKTRACE */
        #else
          #error unsupported architecture
        #endif