Multithreaded App won't work in release build.


I am having a problem with a Multithreaded MFC application. The application works
with a Debug build, however as soon as I change to a Release build,
the program reports an Access Violation after I send a message to the second thread.

I have included AfxCheckMemory() and _heapchk() checks for memory corruption
in the debug build and they don't report any errors. I have also removed all the code that is
doing any "work" from the second thread and the application still crashes.

Any ideas where I should start looking for the problem? I've included a brief description of the code
below and the call stack from the Debug and Release builds below. The call stack on the
Release build looks wrong to me...

The application is a MFC SDI application. The main CWinApp thread handles all interaction
with the user (input and display). The CWinThread is used as to handle communications via a CSocket.
The main thread sends messages to the second thread using PostThreadMessage(). The thread crashes in the
release version after processing the message - The message arrives in the correct procedure, but
as I continue to step through the code it appears to jump to the middle of nowhere when leaving
CWinThread::PreTranslateMessage()


The relavent bits of the thread code:

IMPLEMENT_DYNAMIC(CChannelThread, CWinThread)

CChannelThread::CChannelThread(CWnd* pWnd, CChannelThreadInfo* pChannelThreadInfo)
{

      m_bAutoDelete = FALSE;
      m_pMainWnd = pWnd;
}

CChannelThread::~CChannelThread()
{
}

int CChannelThread::InitInstance()
{
      ASSERT(AfxCheckMemory());
      online = false;
      return true;
}

void CChannelThread::ConnectChannel()
{
      ASSERT(AfxCheckMemory());
      if(_heapchk()!=_HEAPOK)
            DebugBreak();
}

BEGIN_MESSAGE_MAP(CChannelThread, CWinThread)
      //{{AFX_MSG_MAP(CChannelThread)
            // NOTE - the ClassWizard will add and remove mapping macros here.
            ON_THREAD_MESSAGE(WM_USER_CONNECT, ConnectChannel)
            ON_THREAD_MESSAGE(WM_USER_SEND, OnSendMessage)
            ON_THREAD_MESSAGE(WM_USER_DISCONNECT, OnDisconnect)
            ON_THREAD_MESSAGE(WM_USER_ONLINE, OnOnLine)
      //}}AFX_MSG_MAP
END_MESSAGE_MAP()



The code used to start the thread (in the main View of CWinApp):

      m_pChannelThread = new CChannelThread(this, &m_ChannelThreadInfo);
      !m_pChannelThread->CreateThread();


The code used to send the message to the thread:


  if (!m_pChannelThread->PostThreadMessage(WM_USER_CONNECT, 0,0))
  {
         return ID_ERR_ABORT;
  }

  if (WaitForSingleObject(m_hdlEventConnected, 10000) != WAIT_OBJECT_0)
 

The Call stack for the RELEASE version:

CChannelThread::ConnectChannel(unsigned int 0x0012def8) line 74
CWinThread::DispatchThreadMessageEx(CWinThread * const 0x00001234 {CWinThread h=??? proc=???}, tagMSG * 0x5f41ab91 {msg=0xfffe7ecc wp=0x3d04478b lp=0x00000100}) line 652
CWinThread::PreTranslateMessage(CWinThread * const 0x00001234 {CWinThread h=??? proc=???}, tagMSG * 0x5f4011c5 {msg=0x9415ff57 wp=0x575f4d06 lp=0x061415ff}) line 660 + 15 bytes
CWinThread::PumpMessage(CWinThread * const 0x00001234 {CWinThread h=??? proc=???}) line 859 + 17 bytes
CWinThread::Run(CWinThread * const 0x00001234 {CWinThread h=??? proc=???}) line 480 + 5 bytes
MFC42! 5f420f79()
CChannelThread::`scalar deleting destructor'(unsigned int 0x004190a8) address 0x00402d60


The Call stack for the DEBUG version:

CChannelThread::ConnectChannel() line 69
CWinThread::DispatchThreadMessageEx(tagMSG * 0x00803608 {msg=0x00008001 wp=0x00000000 lp=0x00000000}) line 652
CWinThread::PreTranslateMessage(tagMSG * 0x00803608 {msg=0x00008001 wp=0x00000000 lp=0x00000000}) line 660 + 20 bytes
CWinThread::PumpMessage() line 859 + 30 bytes
CWinThread::Run() line 480 + 11 bytes
_AfxThreadEntry(void * 0x006df2ec) line 126 + 11 bytes
_threadstartex(void * 0x00803680) line 212 + 13 bytes
KERNEL32! bff86da1()
KERNEL32! bff84837()
KERNEL32! bff84734()


Any help would be greatly appreciated.

Regards,

Ron.
omega1Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

mikeblasCommented:
Your message-handling function is incorrectly prototyped, and that's irrecoverably corrupting your stack in your RELEASE build. (In a debug build, you can often get away with it because the compiler doesn't party on the stack as aggressively as it normally does.)

Your crash has nothing to do with the heap.

You should code:


void CChannelThread::ConnectChannel(WPARAM wParam, LPARAM lPARAM)
{
   return 0L;
}

If you don't need to use the parameters, you still need to provide them but you can avoid warnings by not providing formal declarations:


void CChannelThread::ConnectChannel(WPARAM, LPARAM)
{
   return 0L;
}


.B ekiM
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
omega1Author Commented:
You are correct! this was the cause of all my problems.

Thank you for the assistance.


0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
System Programming

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.