[Bug c++/36030] New: Throwing exceptions in multiple threads leads to spinning in call to _Unwind_Find_FDE

2008-04-23 Thread an at atrn dot org
gcc/unwind-dw2-fde-glibc.c maintains a cache of frames via its dl_iterate_phdr
callback but doesn't protect against multiple threads modifying that cache
concurrently.  A simple test program that starts N threads, all of which
immediately throw, often, but not always (as such races are prone to behave),
leads to some number of threads stuck inside their stack unwinding consuming
100% CPU.  The particular failure mode will no doubt differ depending upon the
particular interleaving of accesses/modifications to the cache structure but
I'm seeing consistent hangs on the two systems on which I've tested this (quad
core Xeon, dual core Core 2 Duo).

Reproduction typically requires running the test in a loop until it doesn't
exit.  The usual caveats regarding races apply, i.e it may not fail on certain
CPU/OS combinations or may take a long time to fail.

The attached patch avoids the spinning by grabbing "object_mutex" (defined in
gcc/unwind-dw2-fde.c which is included and used in gcc/unwind-dw2-fde-glibc.c)
to protect against multiple threads manipulating the cache at the same time.

With the patch no failure has been observed in over 200,000 invocations of the
test with each invocation starting 100 threads.

The issue was found on FreeBSD 7.x (aka STABLE) gcc 4.2.1 (20070719) but
inspection of the VCS shows the same code exists on the trunk and branches.


-- 
   Summary: Throwing exceptions in multiple threads leads to
spinning in call to _Unwind_Find_FDE
   Product: gcc
   Version: 4.2.1
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c++
AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: an at atrn dot org
 GCC build triplet: i386-undermydesk-freebsd
  GCC host triplet: i386-undermydesk-freebsd
GCC target triplet: i386-undermydesk-freebsd


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



[Bug c++/36030] Throwing exceptions in multiple threads leads to spinning in call to _Unwind_Find_FDE

2008-04-23 Thread an at atrn dot org


--- Comment #1 from an at atrn dot org  2008-04-23 21:22 ---
Created an attachment (id=15521)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15521&action=view)
test program

Test program to demonstrate issue


-- 


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



[Bug c++/36030] Throwing exceptions in multiple threads leads to spinning in call to _Unwind_Find_FDE

2008-04-23 Thread an at atrn dot org


--- Comment #2 from an at atrn dot org  2008-04-23 21:25 ---
Created an attachment (id=15522)
 --> (http://gcc.gnu.org/bugzilla/attachment.cgi?id=15522&action=view)
Patch to protect against concurrent modifications to frame cache

Simple fix that applies coarse-grained locking around the frame cache.  If
unwinding performance is a concern either a finer-grain locking strategy or
even a lock-free structure should be used.


-- 


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



[Bug other/36030] Throwing exceptions in multiple threads leads to spinning in call to _Unwind_Find_FDE

2008-04-23 Thread an at atrn dot org


--- Comment #3 from an at atrn dot org  2008-04-23 21:36 ---
Note for repro using glibc, the test program uses the BSD err() function to
report errors and quit.  A quick look at glibc's manual says it has a
compatible err() function but declared in error.h not err.h as in BSD.


-- 

an at atrn dot org changed:

   What|Removed |Added

 CC|    |an at atrn dot org


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



[Bug other/36030] Throwing exceptions in multiple threads leads to spinning in call to _Unwind_Find_FDE

2008-04-24 Thread an at atrn dot org


--- Comment #5 from an at atrn dot org  2008-04-25 05:27 ---
> Which glibc version do you use?

As per description it's FreeBSD 7's (aka STABLE) libc who's ld.so
implementation uses gcc's glibc-specific unwinding.

>  You should probably report this as a bug to your vendor.

Done with patch to fix it.

http://www.freebsd.org/cgi/query-pr.cgi?pr=123062

Thanks for the clarification.


-- 


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