Re: Strange crash reported from winQual. Is it caused by _endthreadex?
"Anthony Wieser" wrote:
I have a thread that I launch as follows in C++:
BOOL CMyThread::CreateThread()
{
unsigned threadid;
m_hThread = (HANDLE) _beginthreadex(NULL, 0,
CMyThread::BeginThread, this, 0, &threadid);
return (m_hThread != (HANDLE) -1);
}
static unsigned __stdcall CMyThread::BeginThread(void
*parg)
{
((CMyThread *) parg)->InitInstance();
int ret_val = ((CMyThread *) parg)->ExitInstance();
_endthreadex(ret_val);
return ret_val;
}
{
...
CMyThread *pNewThread = new CMyThread();
pNewThread->CreateThread();
...
}
I'm calling _endthreadex because it suggests I should in
some samples. However, I'm starting to wonder if it's
necessary or desirable.
You should call `_endthreadex' only if you want to exit from
the thread prematurely AND you cannot just return from
thread function. For example:
void foo()
{
if(serious error)
{
_endthreadex(42);
}
// normal flow
}
unsigned __stdcall threadfunc(void* p)
{
// ...
foo();
// ...
return 0;
}
Otherwise calling `_endthreadex' is redundant. It is because
`_beginthreadex' already calls `_endthreadex' upon return
from your thread routine. In pseudocode `_beginthreadex'
looks roughly like this:
int _beginthreadex(start_address, params, ...)
{
// ...
__try
{
_endthreadex(start_address(params));
}
__except(...)
{
_exit(exception_code);
}
}
My real problem is that I'm getting a strange crash dump
on my WinQual account.
I have doubts that `_endthreadex' is a culprit here. In
worst case it's redundant.
I can see that you allocate thread object from heap. Could
it be that the object is deleted too early? Also, I noticed
that you call `InitInstance' and `ExitInstance' methods on
the thread object. Do you use MFC? If yes, then you should
create threads with `AfxBeginThread' instead of
`_beginthreadex':
<MSDN quote>
The CWinThread class is necessary to make your code and MFC
fully thread-safe. Thread-local data used by the framework
to maintain thread-specific information is managed by
CWinThread objects. Because of this dependence on CWinThread
to handle thread-local data, any thread that uses MFC must
be created by MFC. For example, a thread created by the
run-time function _beginthread, _beginthreadex cannot use
any MFC APIs.
</quote>
HTH
Alex