[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