Opened 6 years ago

Closed 6 years ago

#12400 closed Bugs (worksforme)

libunwind fails to detect end-of-stack with boost::context

Reported by: mmayorga@… Owned by: olli
Milestone: To Be Determined Component: context
Version: Boost 1.56.0 Severity: Problem
Keywords: libunwind context coroutine Cc:

Description

make_fcontext initialises a new stack, but it is making libunwind not to find its termination, presumably because it is initialising it by pointing to a call to program exit.

Problematic source: https://github.com/boostorg/context/blob/develop/src/asm/make_x86_64_sysv_elf_gas.S

leaq -0x40(%rax), %rax moves the stack pointer down 64 bytes The top thing on the stack at the highest address is what the comment calls EXIT, and is a pointer to the finish label. There is nothing after that No frame where RBP is null or an undefine dIP Boost does not put anything after that at all

From libunwind sources: file Gstep.c, end-of stack detection algorithm:

/* x86_64 ABI specifies that end of call-chain is marked with a NULL RBP or undefined return address */

if (DWARF_IS_NULL_LOC (c->dwarf.loc[RBP])

DWARF_IS_NULL_LOC(c->dwarf.loc[c->dwarf.ret_addr_column]))

{

c->dwarf.ip = 0; ret = 0;

}

Change History (9)

comment:1 by mmayorga@…, 6 years ago

A patch that solves the issue is:

Index: boost_1_56_0/libs/context/src/asm/make_x86_64_sysv_elf_gas.S
===================================================================
--- boost_1_56_0.orig/libs/context/src/asm/make_x86_64_sysv_elf_gas.S
+++ boost_1_56_0/libs/context/src/asm/make_x86_64_sysv_elf_gas.S
@@ -61,6 +61,9 @@ make_fcontext:
     /* will be entered after context-function returns */
     movq  %rcx, 0x40(%rax)
 
+    /* BP 1st frame to be 0 */
+    movq  $0, 0x30(%rax)
+
     ret /* return pointer to context-data */
 
 finish:

comment:2 by mmayorga@…, 6 years ago

Keywords: coroutine added
Version: Boost Development TrunkBoost 1.56.0

comment:3 by mmayorga@…, 6 years ago

movq $0, 0x30(%rax) better implemented using xor rax,rax

in reply to:  3 comment:4 by mmayorga@…, 6 years ago

Replying to mmayorga@…:

movq $0, 0x30(%rax) better implemented using xor rax,rax

I meant movq $0, 0x30(%rax) better implemented using xorq if possible with 0x30(%rax)

comment:5 by olli, 6 years ago

your code seams to be false because RIP (address of context-fn) is stored as RIP in 0x30(%rax). the address of the label 'finish' is stored as the return address for the context-fn (e.g. if the context-fn returns, a branch to label 'finish' happens).

Last edited 6 years ago by olli (previous) (diff)

comment:6 by olli, 6 years ago

I've added an example backtraceing the call stack (using libunwind) - seams to work on x86_64.

Last edited 6 years ago by olli (previous) (diff)

comment:7 by mmayorga@…, 6 years ago

I'll make and upload a reproducer...

comment:8 by olli, 6 years ago

I close this bug report - works for me (example/v2/backtrace.cpp - needs to be enabled in Jamfile.v2).

comment:9 by olli, 6 years ago

Resolution: worksforme
Status: newclosed
Note: See TracTickets for help on using tickets.