Solved

Multithreaded App won't work in release build.

Posted on 1998-04-25
2
484 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
2 Comments
 
LVL 11

Accepted Solution

by:
mikeblas earned 200 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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
has77  challenge 9 68
zeroFront challenge 7 71
changeXy challenge 13 58
mapBully challenge 6 93
Here is how to use MFC's automatic Radio Button handling in your dialog boxes and forms.  Beginner programmers usually start with a OnClick handler for each radio button and that's just not the right way to go.  MFC has a very cool system for handli…
Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
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.
Access reports are powerful and flexible. Learn how to create a query and then a grouped report using the wizard. Modify the report design after the wizard is done to make it look better. There will be another video to explain how to put the final p…

743 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

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now