Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Multithreaded App won't work in release build.

Posted on 1998-04-25
2
Medium Priority
?
499 Views
Last Modified: 2013-11-19

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.
0
Comment
Question by:omega1
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
2 Comments
 
LVL 11

Accepted Solution

by:
mikeblas earned 800 total points
ID: 1302132
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
 

Author Comment

by:omega1
ID: 1302133
You are correct! this was the cause of all my problems.

Thank you for the assistance.


0

Featured Post

Survive A High-Traffic Event with Percona

Your application or website rely on your database to deliver information about products and services to your customers. You can’t afford to have your database lose performance, lose availability or become unresponsive – even for just a few minutes.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This tutorial will teach you the special effect of super speed similar to the fictional character Wally West aka "The Flash" After Shake : http://www.videocopilot.net/presets/after_shake/ All lightning effects with instructions : http://www.mediaf…

705 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question