[Gc] C++ exceptions problem

Filip Pizlo pizlo at mac.com
Mon Jan 16 22:35:18 PST 2006


(Sorry if this is too many mails.)  I implemented something like this  
in the C++ runtime that ships with GCC 4.0.2.  And of course, it  
makes C++ exceptions work correctly.

I am just curious, is this the best way of solving this problem?  Or  
am I overlooking a simpler solution?

--
Filip


On Jan 16, 2006, at 5:04 PM, Filip Pizlo wrote:

> Just some clarification in this matter:  looking at the GCC 4.0  
> source, it looks like the exception "slot" that a C++ exception is  
> stored in while "in transit" is allocated using malloc.  The  
> relevant code is in libstdc++-v3/libsupc++/eh_alloc.cc in the GCC  
> source.  It seems that one hackish approach (other than asking the  
> collector to override malloc/free) would be to override  
> __cxxabicv1::__cxa_allocate_exception(size_t) and  
> __cxxabiv1::__cxa_free_exception(void*).
>
> But I don't like that approach, since the allocate_exception  
> function needs to also do C++-runtime-specific bookkeeping.
>
> To me it seems like it would be perfectly reasonable to patch the C+ 
> + runtime so that the malloc/free routines that are used for  
> exception-related allocation can be configured dynamically, say  
> with a call like:
>
> __gnu_ext::__set_exception_malloc(void *(*malloc)(size_t), void 
> (*free)(void*)) throw();
>
> This will require a small patch to the C++ runtime as well as a  
> small addition to the GC (the collector could call this function  
> during GC_INIT).  Thoughts?
>
> --
> Filip
>
>
>
> On Jan 16, 2006, at 3:19 PM, Filip Pizlo wrote:
>
>> Hello,
>>
>> It seems that there is a bad interaction between the collector and  
>> C++ exceptions.  When thrown, a C++ exception seems to be stored  
>> in some thread-local storage arranged for by the runtime.  This  
>> storage location is overlooked by the collector, so some roots are  
>> missed.  Here's a simple program that demonstrates the problem:
>>
>> #include <gc/gc.h>
>> #include <string.h>
>> #include <stdio.h>
>>
>> struct myexc {
>>     char *str;
>> };
>>
>> void f() {
>>     myexc e;
>>     e.str=(char*)GC_MALLOC_ATOMIC(100);
>>     strcpy(e.str,"hello, world!");
>>     // uncomment for a cheap workaround
>>     //char **strptr=(char**)GC_MALLOC_UNCOLLECTABLE(sizeof(char**));
>>     //*strptr=e.str;
>>     throw e;
>> }
>>
>> void g() {
>>     try {
>>         f();
>>     } catch (...) {
>>         // if you don't see the bug, change 1000 to a bigger  
>> number or do something else here
>>         // that would force a GC.  to see correct behavior,  
>> comment this loop out.
>>         for (unsigned i=0;i<1000;++i) {
>>             char *str=(char*)GC_MALLOC_ATOMIC(100);
>>             strcpy(str,"foobar!");
>>         }
>>         throw;
>>     }
>> }
>>
>> int main() {
>>     try {
>>         g();
>>     } catch (const myexc &e) {
>>         printf("string is: %s\n",e.str);
>>     }
>>     return 0;
>> }
>>
>> The correct behavior would be for the program to print:
>>
>> string is: hello, world!
>>
>> However, if the 1000 iteration loop causes a GC, we see the output:
>>
>> string is: foobar!
>>
>> I've tested this on GCC 3.3 and 4.0 on Mac OS X 10.4.3 and 10.4.4  
>> with gc 6.5 and 6.6.  I've also tested this on an AMD64 machine  
>> running Linux with GCC 3.4.  On the AMD64, I had to substantially  
>> increase the number of iterations to see the bug, though.
>>
>> I wanted to test with latest from CVS, but the sourceforge CVS is  
>> giving me issues right now.  So I tried with 7.0alpha5.  After  
>> fixing a typo in gcconfig.h (#defined instead of #define), it  
>> failed to compile on OS X with the error:
>>
>> mach_dep.c:194:3: #error GC_push_regs cannot be used with threads
>>
>> (I was using autoconf, and ./configured the collector with -- 
>> enable-threads=posix --enable-cplusplus --disable-shared --enable- 
>> static).
>>
>> On the AMD64 machine, 7.0alpha5 built happily, but still had the C+ 
>> + exception problem.
>>
>> --
>> Filip
>>
>>
>> _______________________________________________
>> Gc mailing list
>> Gc at linux.hpl.hp.com
>> http://www.hpl.hp.com/hosted/linux/mail-archives/gc/
>
> _______________________________________________
> Gc mailing list
> Gc at linux.hpl.hp.com
> http://www.hpl.hp.com/hosted/linux/mail-archives/gc/



More information about the Gc mailing list