chacham15
chacham15

Reputation: 14251

Why is _beginthreadex failing with ERROR_INVALID_ACCESS?

I have a bunch of QWebViews rendered onto a widget. There comes a point at which I start getting the error QThread::start: Failed to create thread (The access code is invalid.). Looking at the Qt source, it appears that _beginthreadex is returning a null handle and errno is ERROR_INVALID_ACCESS, but I have no idea why.

Here is the backtrace at the printing of the error:

0   qErrnoWarning                           qglobal.cpp    2451    0x69ccdd3c  
1   QThread::start                          qthread_win.cpp 469 0x69cd5831  
2   QThreadPoolPrivate::tryStart            qthreadpool.cpp 203 0x69ccc3f5  
3   QThreadPool::start                      qthreadpool.cpp 474 0x69cccdf4  
4   QHostInfoLookupManager::work            qhostinfo.cpp   633 0x6cb9b071  
5   QHostInfoLookupManager::scheduleLookup  qhostinfo.cpp   652 0x6cb9b143  
6   QHostInfo::lookupHost                   qhostinfo.cpp   202 0x6cb9a220  
7   qt_qhostinfo_lookup                     qhostinfo.cpp   722 0x6cb9b4b6  
8   QAbstractSocket::connectToHostImplementation    qabstractsocket.cpp 1427    0x6cbb17f5  
9   QAbstractSocket::qt_static_metacall     moc_qabstractsocket.cpp 166 0x6cbb4925  
10  QMetaMethod::invoke                     qmetaobject.cpp 1664    0x69dc784f  
11  QMetaObject::invokeMethod               qmetaobject.cpp 1179    0x69dc6d6b  
12  QMetaObject::invokeMethod               qobjectdefs.h   418 0x6cd361dd  
13  QAbstractSocket::connectToHost          qabstractsocket.cpp 1342    0x6cbb13b3  
14  QSslSocket::connectToHostImplementation qsslsocket.cpp  1744    0x6cbc7340  
15  QSslSocket::qt_static_metacall          moc_qsslsocket.cpp  91  0x6cbc93cf  
16  QMetaMethod::invoke                     qmetaobject.cpp 1664    0x69dc784f  
17  QMetaObject::invokeMethod               qmetaobject.cpp 1179    0x69dc6d6b  
18  QMetaObject::invokeMethod               qobjectdefs.h   418 0x6cd361dd  
19  QAbstractSocket::connectToHost          qabstractsocket.cpp 1342    0x6cbb13b3  
20  QSslSocket::connectToHostEncrypted      qsslsocket.cpp  422 0x6cbc55e1  
21  QHttpNetworkConnectionChannel::ensureConnection qhttpnetworkconnectionchannel.cpp   607 0x6cb6191f  
22  QHttpNetworkConnectionPrivate::_q_startNextRequest  qhttpnetworkconnection.cpp  862 0x6cb5e92c  
23  QHttpNetworkConnectionPrivate::queueRequest qhttpnetworkconnection.cpp  501 0x6cb5c57d  
24  QHttpNetworkConnection::sendRequest     qhttpnetworkconnection.cpp  931 0x6cb5edf2  
25  QHttpThreadDelegate::startRequest       qhttpthreaddelegate.cpp 291 0x6cb8912a  
26  QHttpThreadDelegate::qt_static_metacall moc_qhttpthreaddelegate_p.cpp   113 0x6cbd147c  
27  QMetaCallEvent::placeMetaCall           qobject.cpp 525 0x69dcf91c  
28  QObject::event                          qobject.cpp 1195    0x69dd08db  
29  QApplicationPrivate::notify_helper      qapplication.cpp    4551    0x2582f44   
30  QApplication::notify                    qapplication.cpp    3933    0x25808b7   
31  QCoreApplication::notifyInternal        qcoreapplication.cpp    915 0x69dc0dc6  
32  QCoreApplication::sendEvent             qcoreapplication.h  231 0x69e35185  
33  QCoreApplicationPrivate::sendPostedEvents   qcoreapplication.cpp    1539    0x69dc1d2a  
34  qt_internal_proc                        qeventdispatcher_win.cpp    496 0x69de2590  
35  USER32!OffsetRect                       C:\Windows\syswow64\user32.dll  0   0x74cc62fa  
36  ??      0   0x152404    
37  ??      0   0x401   
38  ??      0       

The code at the call looks like:

d->handle = (Qt::HANDLE) _beginthreadex(NULL, d->stackSize, QThreadPrivate::start, //d->stackSize is 0
                                            this, CREATE_SUSPENDED, &(d->id));

if (!d->handle) {
    qErrnoWarning(errno, "QThread::start: Failed to create thread");
    d->running = false;
    d->finished = true;
    return;
}

Why is this happening and how do I fix it?

EDIT: also of note, there are exactly 500 threads at the point in which this breaks.

Upvotes: 0

Views: 2734

Answers (1)

nobody
nobody

Reputation: 20174

There's a good chance you've run out of free address space in your process (for thread stacks) after creating 500 threads. On 32-bit Windows, processes only get 2GB of address space by default (the upper half of the address space being reserved for the kernel). 500 1MB thread stacks (the default size, Qt may go higher or lower) plus all the other allocations your process makes could easily be using that up.

See this Old New Thing article for more.

Possible fixes:

  1. If you know your QThreads don't need very big stacks, you can call QThread::setStackSize() to set a smaller size before starting the thread.
  2. Consider using a thread pool and/or just reducing the number of concurrent threads you start. It's unlikely that you have enough CPU cores to make 500+ threads productive.
  3. Use the Windows /3GB switch and make your application LARGE ADDRESS AWARE to get 3GB of user-mode address space.
  4. Go 64-bit (for 63 bits of user-mode address space).

Upvotes: 4

Related Questions