We fork a pthread for some Xalan transformation and then wait for a given time
out period. The thread is started with the default cancellation policy that is
"deferred cancellation". If the thread does not finish we call pthread_cancel
on the thread.  Here is the partial stack trace when it crashes.

#0  0x0000002a95e9f25d in raise () from /lib64/tls/libc.so.6
#1  0x0000002a95ea0a5e in abort () from /lib64/tls/libc.so.6
#2  0x000000000238072d in _Unwind_SetGR (context=0x47d6, index=18443, val=6)
    at
/usr/releng/tools/gcc/build-4.1.1_libstdcxx_debug/gcc-4.1.1/gcc/unwind-dw2.c:179
#3  0x000000000237a543 in __gxx_personality_v0 (version=<value optimized out>, 
    actions=<value optimized out>, exception_class=<value optimized out>, 
    ue_header=0x4dc15d80, context=0x4dc12c40)
    at
/usr/releng/tools/gcc/build-4.1.1_libstdcxx_debug/gcc-4.1.1/libstdc++-v3/libsupc++/eh_personality.cc:672
#4  0x0000002ab20249e5 in ?? () from /lib64/libgcc_s.so.1
#5  0x0000002ab2024afc in _Unwind_ForcedUnwind () from /lib64/libgcc_s.so.1
#6  0x0000002a95adcdd0 in __pthread_unwind () from /lib64/tls/libpthread.so.0
#7  0x0000002a95f6b918 in __pthread_unwind () from /lib64/tls/libc.so.6
#8  0x0000002a95f43ddb in __libc_enable_asynccancel ()
   from /lib64/tls/libc.so.6
#9  0x0000002a95f2ac43 in open () from /lib64/tls/libc.so.6
#10 0x0000002a95ed5188 in _IO_new_file_fopen () from /lib64/tls/libc.so.6
#11 0x0000002a95ecbf34 in __fopen_internal () from /lib64/tls/libc.so.6
#12 0x00000000020c025b in xercesc_2_7::XMLPlatformUtils::openFile ()

I tried to debug this a bit and see why this is happening. This is crashing in 
the following function:

/* Overwrite the saved value for register REG in CONTEXT with VAL.  */

inline void
_Unwind_SetGR (struct _Unwind_Context *context, int index, _Unwind_Word val)
{
  int size;
  void *ptr;

  index = DWARF_REG_TO_UNWIND_COLUMN (index);
  gcc_assert (index < (int) sizeof(dwarf_reg_size_table));
  size = dwarf_reg_size_table[index];
  ptr = context->reg[index];

  if (size == sizeof(_Unwind_Ptr))
    * (_Unwind_Ptr *) ptr = val;
  else
    {
      gcc_assert (size == sizeof(_Unwind_Word));
      * (_Unwind_Word *) ptr = val;
    }
}

While running under gdb I found that all entries in dwarf_reg_size_table is 0
and so size becomes 0. When it is compared with  sizeof(_Unwind_Word) i.e., it
causes gcc asserts.

Looking in unwind-dw2.c it seems the table should be initialized before any
calls to the function and my feeling is that the initialization is not
happening.


It is a deterministic bug and I can reproduce it easily. I do not know much
about gcc and so I do not know what all pertinent information is needed. So let
me know what all information you need. 


System: Linux 2.6.9-67.0.15.ELsmp #1 SMP Tue Apr 22 13:58:43 EDT 2008 x86_64
x86_64 x86_64 GNU/Linux


-- 
           Summary: Segafult in gcc/unwind-dw2.c
           Product: gcc
           Version: 4.1.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: sushants at yahoo-inc dot com


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42788

Reply via email to