This is the mail archive of the mailing list for the pthreas-win32 project.

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

Re: Bug report with source code attached

John Bossom wrote:

>Secondly, since your threads are SO short, they could actually
>run to completion BEFORE you actually call pthread_detach.

I agree, this is certainly a bug in my test program. I rewrote it to
incorporate this change (and also Dave's fix of adding a
pthread_attr_destroy so as to not leak memory) and ... well, it
takes much, much longer to crash now, but it does still crash.
I've included the code below. As I said earlier, it doesn't really
matter which clause of the if statement you use -- it will crash
either way.

>[...] Select "Process" and find your process name.
>Next add appropriate counters such as Private Bytes, etc. to monitor
>your resource consumption.

OK, I did this (and also watched it under the task manager -- you can turn
columns for things like handles).  If I run it without -l (i.e., I run it so
that the second, simpler clause of the if is taken), it does seem to leak
handles -- very, very slowly. After 2.5 hours it was up to 450 handles. This
number does steadily rise as the program runs. I don't think the crash
is caused by running out of handles -- if you write a simple test program
that creates joinable threads and never joins them, you'll see that you
can use up tens of thousands of handles before the program wil die.

It seems to leak handles in -l mode as well (and at a faster rate), but I
haven't let it run long enough to be too sure.


// Call with -l argument to cause a crash.
// Compiled with MSVC6 using these args:
//   -nologo -D WIN32 -D _WINDOWS -ML -MTd -GX -Od -G6 -W3 -Zi
#include "pthread.h"
#include <assert.h>

void *NOP1(void *p) { return NULL; }
void *NOP2(void *p) { assert(pthread_detach(pthread_self()) == 0); return NULL; }

main(int argc, char **argv)
    bool lose = (argc == 2 && !strcmp(argv[1], "-l"));
    for (;;) {
        int retval;
        pthread_t tid;

        if (lose) {
            pthread_attr_t attr;
            retval = pthread_attr_init(&attr);
            assert(retval==0);          // success
            retval = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
            assert(retval==0);          // success
            retval = pthread_create(&tid, &attr, NOP1, NULL);
            retval = pthread_attr_destroy(&attr);
        else {
            // actually, this loses too!
            retval = pthread_create(&tid, NULL, NOP2, NULL);
            assert(retval==0);          // success
    return 0;

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