[Gc] C++ exceptions problem

Filip Pizlo pizlo at mac.com
Mon Jan 16 12:19:33 PST 2006


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




More information about the Gc mailing list