Subject: RE: Exception problems-> this is a bug!
From: Joost Kraaijeveld <[email-masked]>
To: "'Town, Brad'" <[email-masked]>
Cc: "Cygwin@Sourceware. Cygnus. Com (E-mail)" <[email-masked]>
Date: Wed, 29 Nov 2000 14:41:15 +0100

> I did have to tweak the source a bit to get it to run.  On my 
> machine, I got
What did you tweak?

> the message "couldn't dynamically determine load address for
> 'CharToOemBuffA' (handle 0x0), Win32 error 127".  Putting a 
> Sleep between
> the two calls to CreateThread allows the program to run.  
> Looks like the
> assembly in autoload.cc needs to be thread-safe (just like 
> the FIXME above
> it says).
I had to put the Sleep() somewhere else (see the source below). I do not get
the error message you got (maybe it has something to do with a different set
of compiler flags: I noticed you did not use -mthreads).

I suspect it has something to do with the cleaning up of the thread
resources (TLS / stack) on a secondary thread but I cannot find any related
sourcecode in the cywin dll sources. The problem is timing related: making
the sleep too short crashes the program after repeated runs (>4) on my
machine and running the program without Sleep() under strace.exe succeeds.

Is there anyone who can point me in the correct direction? 
What code is inserted by the compiler to get the program running?
Is there any documentation available about thread support design and
implementation? 

Joost Kraaijeveld
Askesis B.V.
Molukkenstraat 14
6524NB Nijmegen
tel: 024-3888063 / 06-51855277
fax: 024-3608416
email: [email-masked]
web: www.askesis.nl 

compile with:
g++ -c -mthreads -g -O0 -Wall  -o"Main.o" Main.cpp
g++ -mthreads -o./ALibTest.exe Main.o

////////////// Source Main.cpp ///////////////
#include <cstdio>
#include <cstdlib>
#include <windows.h>

extern "C" unsigned long WINAPI runFunction1(void* aAThreadFunction)
{
   for ( unsigned long i = 0;i<5;i++)
   {
      printf("%lu\n",i);
   }
   return 0;
}

extern "C" unsigned long WINAPI runFunction2(void* aAThreadFunction)
{
   try
   {
      for ( unsigned long i = 0;i<5;i++)
      {
         printf("%lu\n",i);
      } // <- on a crash, this is where the debugger stops
   }
   catch(...)
   {
   }
//   Sleep(20); // <- without this sleep there will be a crash
   return 0;
}

class ATest
{
   public:
      void print()
      {
         runFunction2(0);
      }
};

extern "C" unsigned long WINAPI runFunction3(void* aAThreadFunction)
{
   ATest t;
   t.print();
   return 0;
}

int main(int argc, char* argv[])
{
   LPTHREAD_START_ROUTINE threadFunction; // function to run

   if(argc == 2)
   {
      switch(atoi(argv[1]))
      {
         case 1: // function without try / catch
         {
            threadFunction = runFunction1;
            break;
         }
         case 2: // function with try / catch
         {
            threadFunction = runFunction2;
            break;
         }
         case 3: // function with object with try / catch
         {
            threadFunction = runFunction3;
            break;
         }
         default:
         {
            printf("Run this program with 1 argument (1,2 or 3), see
source\n ");
            return 1;
         }
      }
   }else
   {
      printf("Run this program with 1 argument (1,2 or 3), see source\n ");
      return 1;
   }

   HANDLE threadHandles[2];
   unsigned long threadIds[2];

   // Create two threads
   threadHandles[0] =
CreateThread(NULL,0,threadFunction,NULL,0,&threadIds[0]);
   threadHandles[1] =
CreateThread(NULL,0,threadFunction,NULL,0,&threadIds[1]);

   // Wait for the threads to end
   WaitForMultipleObjects(2,&threadHandles[0],true,INFINITE);

   return 0;
}

--
Want to unsubscribe from this list?
Send a message to [email-masked]