[Gc] random problem in simple c++ program

Boehm, Hans hans.boehm at hp.com
Wed Dec 12 16:52:35 PST 2007


You should definitely be checking the return value of GC_get_stack_base(), and making sure it's not GC_UNIMPLEMENTED.  If it is, and in cases like this maybe even if it's not, use GC_call_with_stack_base().  If that doesn't help, posting the stack trace at which one of the access violations occurs often provides a hint.  Checking that you're getting reasonable stack base values would also be good.

Hans

> -----Original Message-----
> From: gc-bounces at napali.hpl.hp.com
> [mailto:gc-bounces at napali.hpl.hp.com] On Behalf Of Achilleas
> Margaritis
> Sent: Wednesday, December 12, 2007 10:17 AM
> To: gc at napali.hpl.hp.com
> Subject: [Gc] random problem in simple c++ program
>
> Hi,
>
> I've got a big problem: the GC randomly crashes in a very
> simple C++ program that does the following:
>
> 1) the main thread creates a thread which spawns 10
> allocation threads.
> 2) each allocation thread allocates a certain number of GC'd blocks.
> 3) the cleanup routine waits for threads to terminate.
>
> I am using pthreads-win32 with the GC, registering threads on
> my own, using GC_register_my_thread.
>
> I've got a different (seemingly random) problem each time I
> run the program:
>
> 1) stack pointer out of range: "GC Warning: Thread stack pointer
> 0xa6f784 out of range, pushing everything" appears on the IDE
> output window.
>
> 2) random access violations like "First-chance exception at
> 0x0041f919 in test_gc.exe: 0xC0000005: Access violation
> reading location 0x00a70000"
>
> 3) a random access violation which crashes the C runtime
> system with a message. See image at
> http://img141.imageshack.us/img141/232/gcproblem1av6.jpg.
>
> 4) sometimes nothing happens: the program gets stuck in the
> collector loop, without any action.
>
> 5) a message saying 'dirty bit is not setup'. Please see
> image at http://img167.imageshack.us/img167/9956/gcproblem2jz1.jpg.
>
> 6) sometimes I get multiple message boxes from the crt
> runtime terminating in an unusual way:
> http://img254.imageshack.us/img254/7447/gcproblem3fs2.jpg.
>
> 7) Once I got the message 'duplicate large block deallocation'.
>
> Is it something I am doing wrong?
>
> Here is the program's code:
>
> #include <gc.h>
> #include <pthread.h>
> #include <semaphore.h>
> #include <list>
> using namespace std;
>
> //number of allocations per thread
> const int MAX_ALLOC = 100;
>
> //global mutex
> pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
>
> //list of threads
> list<pthread_t> threads;
>
> //required for list of threads
> bool operator == (pthread_t a, pthread_t b) {
>      return pthread_equal(a, b) != 0;
> }
>
> //synchronized add thread
> void add_thread(pthread_t handle) {
>      pthread_mutex_lock(&mutex);
>      threads.push_back(handle);
>      pthread_mutex_unlock(&mutex);
> }
>
> //synchronized remove thread
> void remove_thread(pthread_t handle) {
>      pthread_mutex_lock(&mutex);
>      threads.remove(handle);
>      pthread_mutex_unlock(&mutex);
> }
>
> //synchronized threads empty
> bool threads_empty() {
>      pthread_mutex_lock(&mutex);
>      bool result = threads.empty();
>      pthread_mutex_unlock(&mutex);
>      return result;
> }
>
> //used for allocating random sizes
> int rnd(int i) {
>      return rand() % i;
> }
>
> //allocates memory
> void *allocatorThread(void *p) {
>      //register thread
>      GC_stack_base sb;
>      GC_get_stack_base(&sb);
>      GC_register_my_thread(&sb);
>
>      printf("beginning allocator thread\n");
>
>      //allocate memory
>      for(int i = 0; i < MAX_ALLOC; ++i) {
>          void *p = GC_MALLOC(10 + rnd(1000));
>      }
>
>      printf("ending allocator thread\n");
>
>      //remove thread from list
>      remove_thread(pthread_self());
>
>      //unregister thread
>      GC_unregister_my_thread();
>      return 0;
> }
>
> //the thread that spawns the allocator threads void
> *spawnerThread(void *p) {
>      //register the thread
>      GC_stack_base sb;
>      GC_get_stack_base(&sb);
>      GC_register_my_thread(&sb);
>
>      printf("beginning spawner thread\n");
>
>      //create other threads
>      for(int i = 0; i < 10; ++i) {
>          pthread_t handle;
>          pthread_create(&handle, 0, allocatorThread, 0);
>          add_thread(handle);
>      }
>
>      printf("ending spawner thread\n");
>
>      //remove the thread
>      remove_thread(pthread_self());
>
>      //unregister the thread
>      GC_unregister_my_thread();
>      return 0;
> }
>
> //cleanup; called at exit
> void cleanup() {
>      sem_t sem;
>      sem_init(&sem, 0, 0);
>
>      //periodically check if all threads have terminated
>      while (!threads_empty()) {
>          timespec time = {1, 0};
>          sem_timedwait(&sem, &time);
>      }
>      sem_destroy(&sem);
>
>      pthread_mutex_destroy(&mutex);
> }
>
> //main
> int main() {
>      //init the gc
>      GC_INIT();
>
>      //install an exit handler
>      atexit(cleanup);
>
>      //create and register the main thread
>      pthread_t handle;
>      pthread_create(&handle, 0, spawnerThread, 0);
>      add_thread(handle);
>
>      getchar();
>      return 0;
> }
>
> _______________________________________________
> 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