This is the mail archive of the 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]

LSDA unwind information is off by one (in __gcc_personality_v0)

We have a fun little glibc bug which causes pthread_cond_wait to write out of bounds on i386:

Root cause is this in libgcc/unwind-c.c:

    130   int ip_before_insn = 0;
    158   /* Parse the LSDA header.  */
    159   p = parse_lsda_header (context, language_specific_data, &info);
    160 #ifdef HAVE_GETIPINFO
    161   ip = _Unwind_GetIPInfo (context, &ip_before_insn);
    162 #else
    163   ip = _Unwind_GetIP (context);
    164 #endif
    165   if (! ip_before_insn)
    166     --ip;
    167   landing_pad = 0;

The PC decrement cannot be possibly meaningful on CISC architectures with variable instruction lengths. I suspect it's an unintentional leftover from the ia64 port.

I wonder how GCC itself copes with the decrement in __gcc_personality_v0. This probably matters to Ada the most because it supports asynchronous exceptions by default.

with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with System.Machine_Code; use System.Machine_Code;

procedure Proc is
   Asm ("# BEFORE", Volatile => True);
      B : Unbounded_String;
      Asm ("# WITHIN", Volatile => True);
   Asm ("# AFTER", Volatile => True);
end Proc;

Looking at the assembly, there does not seem to be any adjustment for the off-by-one, but the asynchronous exception handler can be safely executed multiple times (it has an internal guard flag), so maybe this never matters. This off-by-one only matters for the exit from exception handling regions because at the entry, we always get a PC value which is at least one greater than the initial label because on i386 and x86_64, the PC coming in from the kernel points after the last executed instruction.

I guess my question is if this is all working as designed.

If the decrement is ever removed from the libgcc unwinder, we should add a compensating NOP in the glibc code. Otherwise, we can just adjust the unwind tables.


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