This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Unwinding CFI gcc practice of assumed `same value' regs


Hello,

currently (on x86_64) the gdb backtrace does not properly stop at the outermost
frame:

#3  0x00000036ddb0610a in start_thread () from /lib64/tls/libpthread.so.0
#4  0x00000036dd0c68c3 in clone () from /lib64/tls/libc.so.6
#5  0x0000000000000000 in ?? ()

Currently it relies only on clearing %rbp (0x0000000000000000 above is
unrelated to it, it got read from uninitialized memory).

http://sourceware.org/ml/gdb/2004-08/msg00060.html suggests frame pointer 0x0
should be enough for a debugger not finding CFI to stop unwinding, still it is
a heuristic.  In the -fno-frame-pointer compiled code there is no indication
the frame pointer register became a regular one and 0x0 is its valid value.

The right unwinding stop indication should be CFI-undefined PC:
	http://dwarf.freestandards.org/Dwarf3.pdf - page 118 (130/267)
	- If a Return Address register is defined in the virtual unwind table,
	  and its rule is undefined (for example, by DW_CFA_undefined), then
	  there is no return address and no call address, and the virtual
	  unwind of stack activations is complete.

It has been recently patched for glibc clone() (as the outermost frame)
	http://sourceware.org/ml/libc-alpha/2006-11/msg00082.html
but it had to be reverted as the current libgcc_s unwinder is incompatible:
	http://sourceware.org/ml/libc-alpha/2006-12/msg00078.html

Current libgcc_s unwinder does not differentiate between `DW_CFA_undefined' and
`DW_CFA_same_value' as both set a register state to its `REG_UNSAVED'.

Updating its behavior unfortunately relies on another current ABI incoherency
as DWARF specifies all the registers should be `undefined' by default
	http://dwarf.freestandards.org/Dwarf3.pdf - page 111 (123/267)
	- The default rule for all columns before interpretation of the initial
	  instructions is the undefined rule.  However, an ABI authoring body
	  or a compilation system authoring body may specify an alternate
	  default value for any or all columns.

but current gcc produces CFI code assuming the default state of all the
registers is `same value'.

The strictly DWARF compliant gcc behavior would be to initialize all the callee
saved registers to `DW_CFA_same_value' in all the CIE initial instructions
blocks.  This is currently not done and it would introduce a large increase of
`.eh_frame' size, despite the merging of common CIEs.


Therefore (Jakub is) proposing for gcc `compilation system authoring' to define
the default callee saved registers as `same value' and callee unsaved registers
as `undefined'.  It would make the current gcc CFI practice stanards compliant
and the unwinding stop CFI would became clear and -fomit-frame-pointer reliable.


GCC: `unwind-dw2' needs update to differentiate `undefined' and `same value'.
     AFAIK its code (CFI) generator may remain the same.

GLIBC: Reintroduce the patch above utilizing `.cfi_undefined rip'.

GDB: The currently disabled (default `set complaints 0') warnings made obsolete:
     	During symbol reading, incomplete CFI data; unspecified registers (e.g., eax) at 0xfc1400.

Other unwinders: May need fix to support `DW_CFA_undefined', done for libunwind.


Most of the problem analysis by the courtesy of Jakub Jelinek.

Not providing any patches so far until the final solution decision is made.


Regards,
Jan


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]