This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Thread related crash


Christopher Faylor wrote:
> The version of insight that I built works fine for me on Windows XP SP3.
> I just tried the sigint problem test case with it and it worked as
> expected.

OK. One more try: here's an actual STC. It works as expected if compiled
using:
1) gcc-3 -mno-cygwin -o thread_test thread_test.c
2) [1.5] gcc-3 -o thread_test thread_test.c

But crashes on exit if

3) [1.7] gcc-3 -o thread_test thread_test.c
4) [1.7] gcc-4 -o thread_test thread_test.c

Good:
$ ./thread_test.exe
Main startup
Thread 4832: Initializing data structures
Thread 4832: Starting thread
Thread 4940: Thread starting up.
Thread 4940: Parent notified. Now entering main thread loop.
Thread 4832: Thread started
Thread 4832: Thread started. Hit return to exit.
Thread 4940: Time Elapsed: 10000000
Thread 4940: Time Elapsed: 20000000
Thread 4940: Time Elapsed: 30000000
Thread 4940: Time Elapsed: 40000000
Thread 4940: Time Elapsed: 50000000

Thread 4832: About to kill thread
Thread 4940: Thread about to die.
Thread 4832: Thread killed. Exiting


Bad:
$ ./thread_test.exe
Main startup
Thread 3308: Initializing data structures
Thread 3308: Starting thread
Thread 3796: Thread starting up.
Thread 3796: Parent notified. Now entering main thread loop.
Thread 3308: Thread started
Thread 3308: Thread started. Hit return to exit.
Thread 3796: Time Elapsed: 10020000
Thread 3796: Time Elapsed: 20030000
Thread 3796: Time Elapsed: 30040000
Thread 3796: Time Elapsed: 40050000
Thread 3796: Time Elapsed: 50060000
Thread 3796: Time Elapsed: 60070000
Thread 3796: Time Elapsed: 70080000
Thread 3796: Time Elapsed: 80090000
Thread 3796: Time Elapsed: 90100000
Thread 3796: Time Elapsed: 100110000
Thread 3796: Time Elapsed: 110120000
Thread 3796: Time Elapsed: 120130000
Thread 3796: Time Elapsed: 130140000

Thread 3308: About to kill thread
Thread 3796: Thread about to die.
      6 [unknown (0xED4)] thread_test 2548 _cygtls::handle_exceptions:
Error while dumping state (probably corrupted stack)
Segmentation fault (core dumped)

--
Chuck
#include <stdio.h>
#include <windows.h>
#include <stdarg.h>

typedef struct TimeInfo {

    CRITICAL_SECTION cs;        /* Mutex guarding this structure */

    int initialized;            /* Flag == 1 if this structure is
                                 * initialized. */

    HANDLE testThread;          /* Handle to the thread */

    HANDLE readyEvent;          /* System event used to trigger the
                                 * requesting thread when the testThread
                                 * is initialized for the first time */

    HANDLE exitEvent;           /* Event to signal out of an exit handler
                                 * to tell the testThread to shutdown */

    ULARGE_INTEGER firstTime;   /* time that thread was initialized */

    ULARGE_INTEGER lastTime;    /* time that UpdateClockEachSecond was
                                 * last called */
} TimeInfo;

static TimeInfo timeInfo = {
    { NULL },
    0,
    (HANDLE) NULL,
    (HANDLE) NULL,
    (HANDLE) NULL,
    0
};

static void             StopThread (LPVOID arg);
static DWORD WINAPI     ThreadMain (LPVOID arg);
static void             UpdateTimeEachSecond (void);
int    locked_fprintf (FILE *f, const char * fmt, ...) __attribute__ ((format (printf, 2, 3)));
void   InitLock();
void   InitUnlock();
void   IoLock();
void   IoUnlock();


static CRITICAL_SECTION initLock;
static CRITICAL_SECTION ioLock;
static int init = 0;
void
InitLock()
{
  if (!init)
    {
      init = 1;
      InitializeCriticalSection(&ioLock);
      InitializeCriticalSection(&initLock);
    }
  EnterCriticalSection(&initLock);
}
void
InitUnlock()
{
    LeaveCriticalSection(&initLock);
}
void
IoLock()
{
  EnterCriticalSection(&ioLock);
}
void
IoUnlock()
{
    LeaveCriticalSection(&ioLock);
}
int
locked_fprintf (FILE *f, const char * fmt, ...)
{
  va_list ap;
  DWORD id;

  IoLock();
  fprintf (f, "Thread %d: ", GetCurrentThreadId());
  va_start (ap, fmt);
  vfprintf (f, fmt, ap);
  va_end (ap);
  IoUnlock();
}


static void
StopThread (LPVOID unused __attribute__((unused)) )
{
    SetEvent (timeInfo.exitEvent);
    WaitForSingleObject (timeInfo.testThread, INFINITE);
    CloseHandle (timeInfo.exitEvent);
    CloseHandle (timeInfo.testThread);
}

/* No synchronization because InitLock() has been called 
 * before this function is entered via CreateThread.
 */
static DWORD WINAPI
ThreadMain (LPVOID arg)
{
    FILETIME curFileTime;
    DWORD waitResult;

    locked_fprintf (stdout, "Thread starting up.\n");
    /* Get initial system time */

    GetSystemTimeAsFileTime (&curFileTime);
    timeInfo.firstTime.LowPart  = curFileTime.dwLowDateTime;
    timeInfo.firstTime.HighPart = curFileTime.dwHighDateTime;
    timeInfo.lastTime.LowPart  = curFileTime.dwLowDateTime;
    timeInfo.lastTime.HighPart = curFileTime.dwHighDateTime;

    /*
     * Wake up the calling thread.  When it wakes up, it will release the
     * initialization lock.
     */

    SetEvent (timeInfo.readyEvent);

    locked_fprintf (stdout, "Parent notified. Now entering main thread loop.\n");
    /* Run the worker function once a second */

    for ( ; ; )
      {

        /* If the exitEvent is set, break out of the loop. */

        waitResult = WaitForSingleObjectEx (timeInfo.exitEvent, 1000, FALSE);
        if (waitResult == WAIT_OBJECT_0)
          {
            break;
          }
        UpdateTimeEachSecond ();
      }
    locked_fprintf (stdout, "Thread about to die.\n");

    /* lint */
    return (DWORD) 0;
}

static void
UpdateTimeEachSecond()
{
    FILETIME curFileTime;
    ULARGE_INTEGER delta;
    GetSystemTimeAsFileTime (&curFileTime);

    EnterCriticalSection (&timeInfo.cs);

    timeInfo.lastTime.LowPart  = curFileTime.dwLowDateTime;
    timeInfo.lastTime.HighPart = curFileTime.dwHighDateTime;
    delta.QuadPart = timeInfo.lastTime.QuadPart - timeInfo.firstTime.QuadPart;

    LeaveCriticalSection (&timeInfo.cs);
    locked_fprintf (stdout, "Time Elapsed: %llu\n", delta.QuadPart);
}

int main (int argc, char* argv[])
{
  DWORD id;
  char c;

  fprintf (stdout, "Main startup\n");

  if (!timeInfo.initialized)
    {
      InitLock();
      if (!timeInfo.initialized)
        {
          locked_fprintf (stdout, "Initializing data structures\n");

          /* Initialize static storage */
          InitializeCriticalSection (&timeInfo.cs );
          timeInfo.readyEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
          timeInfo.exitEvent = CreateEvent (NULL, FALSE, FALSE, NULL);

          locked_fprintf (stdout, "Starting thread\n");
          timeInfo.testThread = CreateThread (NULL,
                                              8192,
                                              ThreadMain,
                                              (LPVOID) NULL,
                                              0,
                                              &id);
          SetThreadPriority (timeInfo.testThread,
                             THREAD_PRIORITY_HIGHEST);
          /*
           * Wait for the thread just launched to start running,
           * and create an exit handler that will kill it
           */
          WaitForSingleObject (timeInfo.readyEvent, INFINITE);
          locked_fprintf (stdout, "Thread started\n");

          CloseHandle (timeInfo.readyEvent);
          timeInfo.initialized = TRUE;
        }
      InitUnlock();
    }
  locked_fprintf (stdout, "Thread started. Hit return to exit.\n");

  c = fgetc (stdin);
  locked_fprintf (stdout, "About to kill thread\n");
  StopThread ((LPVOID)NULL);
  locked_fprintf (stdout, "Thread killed. Exiting\n");
}

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]