delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2009/10/08/13:38:07

X-Recipient: archive-cygwin AT delorie DOT com
X-SWARE-Spam-Status: No, hits=-3.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS
X-Spam-Check-By: sourceware.org
Message-ID: <4ACE235E.3010108@cwilson.fastmail.fm>
Date: Thu, 08 Oct 2009 13:37:34 -0400
From: Charles Wilson <cygwin AT cwilson DOT fastmail DOT fm>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.23) Gecko/20090812 Thunderbird/2.0.0.23 Mnenhy/0.7.6.666
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: Thread related crash
References: <4ACDCA99 DOT 9090400 AT cwilson DOT fastmail DOT fm> <20091008134822 DOT GD14389 AT ednor DOT casa DOT cgf DOT cx> <4ACE10DB DOT 3010808 AT cwilson DOT fastmail DOT fm> <20091008163738 DOT GA627 AT ednor DOT casa DOT cgf DOT cx>
In-Reply-To: <20091008163738.GA627@ednor.casa.cgf.cx>
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

--------------030200050609090809030809
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

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

--------------030200050609090809030809
Content-Type: text/plain;
 name="thread_test.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="thread_test.c"

#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");
}


--------------030200050609090809030809
Content-Type: text/plain; charset=us-ascii

--
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
--------------030200050609090809030809--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019