Solved

Multithreaded App won't work in release build.

Posted on 1998-04-25
2
490 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

Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Need a Shell script to start a service checking the port 6 50
while loop over for loop 7 101
haveThree challenge 22 116
x-bar in Google Sheets 2 50
Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This Micro Tutorial will teach you how to censor certain areas of your screen. The example in this video will show a little boy's face being blurred. This will be demonstrated using Adobe Premiere Pro CS6.
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.

815 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