[PATCH] libc/x86: fix stack unwinding and backtrace information

Timo Teräs timo.teras at iki.fi
Fri Nov 11 13:40:01 UTC 2011


On 11/11/2011 03:31 PM, Peter Mazinger wrote:
> 
> -------- Original-Nachricht --------
>> Datum: Fri, 11 Nov 2011 13:30:27 +0200
>> Von: "Timo Teräs" <timo.teras at iki.fi>
>> An: 
>> CC: uclibc at uclibc.org
>> Betreff: Re: [PATCH] libc/x86: fix stack unwinding and backtrace information
> 
>> On 11/10/2011 10:21 AM, Timo Teräs wrote:
>>> When compiled without framepointer, the DWARF-2 CFI data is required
>>> for proper stack unwinding.
>>>
>>> This patch adds the CFI information to:
>>>  * syscalls (so we get proper backtrace even for release builds)
>>>  * new thread stub function (so the backtrace is clean for user
>>>    created threads)
>>>
>>> Also pads the signal return trampolines separate from other functions.
>>> If CFI info was found for signal return code (which seems to happen if
>>> it's located right next a valid function), it will not be recognized
>>> as signal trampoline (gcc unwinder and gdb check first CFI info, and
>>> only if it does not exists it compares the exact opcode sequence to
>>> see if we are at signal return code block). This fixes a real crash
>>> if thread is cancelled and the cancellation handler fails to detect the
>>> signal return frame.
>>>
>>> Signed-off-by: Timo Teräs <timo.teras at iki.fi>
>>>
>>> @@ -71,6 +72,8 @@ __asm__ (
>>>  	".if 1 - \\name\n\t"    /* if reg!=ebx... */
>>>  	".if 2 - \\name\n\t"    /* if reg can't be clobbered... */
>>>  	"pushl %ebx\n\t"        /* save ebx on stack */
>>> +	CFI_ADJUST_CFA_OFFSET(4) "\n\t"
>>> +	CFI_REL_OFFSET(ebx, 0) "\n\t"
>>>  	".else\n\t"
>>>  	"xchgl \\reg, %ebx\n\t" /* else save ebx in reg, and load reg to ebx
>> */
>>>  	".endif\n\t"
>>> @@ -89,6 +92,8 @@ __asm__ (
>>>  	".if 1 - \\name\n\t"
>>>  	".if 2 - \\name\n\t"    /* if reg can't be clobbered... */
>>>  	"popl %ebx\n\t"         /* restore ebx from stack */
>>> +	CFI_ADJUST_CFA_OFFSET(-4) "\n\t"
>>> +	CFI_RESTORE(ebx) "\n\t"
>>>  	".else\n\t"
>>>  	"xchgl \\reg, %ebx\n\t" /* else restore ebx from reg */
>>>  	".endif\n\t"
> 
> IIRC the two if's are anyway a bit wrong (looked into it when I added
> DOMULTI config option), I wanted some time ago to convert these to
> the current usage in glibc (where for less arguments the content is
> only exchanged), the only stopper was how to implement _syscall6 for
> PIC code I do not know how much the way of this implementation will
> influence the speed of execution, I can remember someone saying, that
> it is negligible. If so, the way the _syscall5 is done in glibc would
> be a way to implement _syscall6 as well.

Syscalls are *slow*. Whether we do push/pop or 2*xchg sounds very
insignificant to me. My feeling is that on modern CPUs the speed impact
goes exactly the opposite way.

I think *much* greater performance improvement can be achieved if we
implement SYSENTER support instead of the currently hardcoded "int 0x80".

I haven't done any benchmarks about these though...

- Timo


More information about the uClibc mailing list