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


Multithreading problems

Posted on 2001-09-01
Medium Priority
Last Modified: 2013-11-20

there is a problem which I cannot solve so far. In an SDI application I need to send a message from a working thread to the main frame window. In debug version all works fine, but in release version "access violation" happens.

I creating new working thread wih AfxBeginThread() and HWND of main frame is being passed to new thread as a parameter, it waiting for some events and then sending a message to main frame. And in release version when one of these events happens and thread sends message to main frame, unclear things occurs. I builded release version with debug info, and it seems that somewhere in MFC (in threadcore.cpp and wincore.cpp) some mess with HWND happens during translating messages.

This is how stack looking at the moment of error (and what is interesting message 867 (WM_IDLEUPDATECMDUI) is not the message that working thread sending to main frame):
CWnd::AttachControlSite(CWnd * const 0x017b0364 {CMapPtrToPtr}, CHandleMap * 0x017b0360) line 420

CWnd::FromHandle(HWND__ * 0x00000cd8) line 293

CWnd::GetOwner(const CWnd * const 0x017b0364 {CMapPtrToPtr}) line 35 + 22 bytes

CControlBar::OnIdleUpdateCmdUI(CControlBar * const 0x017b0364 {CMapPtrToPtr}, unsigned int 1, long 0) line 687 + 7 bytes

CWnd::OnWndMsg(CWnd * const 0x017b0364 {CMapPtrToPtr}, unsigned int 867, unsigned int 1, long 4677952, long * 0x0073fc54) line 1982 + 8 bytes

CWnd::WindowProc(CWnd * const 0x017b0364 {CMapPtrToPtr}, unsigned int 867, unsigned int 1, long 0) line 1585 + 27 bytes

CControlBar::WindowProc(CControlBar * const 0x017b0364 {CMapPtrToPtr}, unsigned int 867, unsigned int 1, long 0) line 480 + 14 bytes

AfxCallWndProc(CWnd * 0x00000000 {CWnd hWnd=???}, HWND__ * 0x00000ee0, unsigned int 867, unsigned int 1, long 0) line 218

//the function CWnd::SendMessageToDescendants() calls
//AfxCallWndProc() in such a way:
//  if (pWnd != NULL)
//  {
//    AfxCallWndProc(pWnd, pWnd->m_hWnd, message, wParam, lParam);
//  }
//In other words CWnd* in AfxCallWndProc cannot be NULL,
//but we see the opposite

CWnd::SendMessageToDescendants(HWND__ * 0x00000cd8, unsigned int 867, unsigned int 1, long 0, int 1, int 1) line 2309

CWnd::SendMessageToDescendants(HWND__ * 0x00000fc8, unsigned int 867, unsigned int 1, long 0, int 1, int 1) line 2318 + 21 bytes

CWinThread::OnIdle(CWinThread * const 0x017b0364 {CMapPtrToPtr}, long 4507474) line 551

CWinApp::OnIdle(CWinApp * const 0x017b0364 {CMapPtrToPtr}, long 0) line 480

CWinThread::Run(CWinThread * const 0x017b0364 {CMapPtrToPtr}) line 472 + 16 bytes

CWinApp::Run(CWinApp * const 0x017b0364 {CMapPtrToPtr}) line 399 + 7 bytes

AfxWinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x801adfa2, int 1) line 49 + 7 bytes

WinMain(HINSTANCE__ * 0x00400000, HINSTANCE__ * 0x00000000, char * 0x801adfa2, int 1) line 30

MYAPPLICATION! WinMainCRTStartup + 224 bytes

This is piece of code where exception is being throwed:
void CWnd::AttachControlSite(CHandleMap* pMap)
  if (this != NULL && m_pCtrlSite == NULL)
    // Determine if parent is an OLE control container
    CWnd* pWndParent = (CWnd*)pMap->LookupPermanent

    if (pWndParent != NULL && pWndParent->m_pCtrlCont
           != NULL)

// delegate through helper in COleControlSite
exception here
===>>  pWndParent->m_pCtrlCont->AttachControlSite(this);

This is how "this" looking at the moment of error:
-      this      0x017b0364 {CMapPtrToPtr}
+      [CMapPtrToPtr]      {CMapPtrToPtr}
+      CCmdTarget      {CCmdTarget}
+      classCWnd      {"CWnd"}
+      m_hWnd      0x0047760c const  CMapPtrToPtr::`vftable'
+      wndTop      {CWnd hWnd=0x00000000}
+      wndBottom      {CWnd hWnd=0x00000001}
+      wndTopMost      {CWnd hWnd=0xffffffff}
+      wndNoTopMost      {CWnd hWnd=0xfffffffe}
+      m_hWndOwner      0x00000000
      m_nFlags      7
      m_pfnSuper      0x00000000
      m_nMsgDragList      51462
      m_nModalResult      0
+      m_pDropTarget      0x00000000 {COleDropTarget}
+      m_pCtrlCont      0x00000004 {COleControlContainer}
+      m_pCtrlSite      0x00472ec8 {CMapPtrToPtr}
+      _messageEntries      0x00472f18
+      messageMap      {...}    

Can someone to shed some light upon that problem?
Question by:mnbmnb
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
  • 4
  • 3
  • 2
  • +4
LVL 32

Expert Comment

ID: 6448687
>>In debug version all works fine, but in release
>>version "access violation" happens.

Any time I hear this it boils down to the same problem.  You are overwriting one or more memory locations in your program.  The DEBUG build pads memory allocation and fills them with a pattern so as to detect when adjacent memory locations get overwritten.  The RELEASE build doesn't do this.

The simplest way to find this is to run the DEBUG build in the DEBUGGER.  You'll get a warning when the problem happens as the DEBUG runtime libraries detect the memory overwrite problem.

Author Comment

ID: 6448734
>>In debug version all works fine, but in release
>>version "access violation" happens.

>Any time I hear this it boils down to the same problem.  

Well, it seems that when you read this two strings, you did not read any further. Access violation in my case happens not because of memory overwriting, but because of that there is try of operation with zero object.
LVL 32

Expert Comment

ID: 6448750
Well, I guess it's clear that you have this solved....
Learn how to optimize MySQL for your business need

With the increasing importance of apps & networks in both business & personal interconnections, perfor. has become one of the key metrics of successful communication. This ebook is a hands-on business-case-driven guide to understanding MySQL query parameter tuning & database perf


Expert Comment

ID: 6448939
are you sending or posting? MFC CWnd objects are not thread safe due to all the message maps - however I'd have expected it to crash in debug to is this was the case.

If it is not necessary to do a sendmessage then try postmessage and use plain SDK (since you have the HWND) so you don't create any superflous MFC objects

eg if your sendmessage was like this

CMyDataObject obj;

then change it to

CMyDataObject *pobj=new CMyDataObject; // delete in message handler


Author Comment

ID: 6449021

I posting and I even do not passing with message any pointer. Only message with lParam and wParam as zeroes. I tryed to change the receiver of message from the main frame to view, but effect is the same: after handling my message program crashed because of in CWnd class member m_pCtrlSite which was zero before handling my message appears some garbage and CWnd's functions begin trying to access this member as follows:

CWnd* CWnd::SetFocus()

     if (m_pCtrlSite == NULL)
          return CWnd::FromHandle(::SetFocus(m_hWnd));
          return m_pCtrlSite->SetFocus();

Things seems like the CWnd object becomes corrupt after handling my message. And I have no idea why. The most interesting that in debug version I have no any warning and all works perfectly.

Author Comment

ID: 6449030
It need not to say that handling of my message does not touch m_pCtrlSite in any way.

Expert Comment

ID: 6449901
what does your handler look like ?


ON_MESSAGE( <message>, <memberFxn> ) afx_msg LRESULT memberFxn(WPARAM, LPARAM);
ON_REGISTERED_MESSAGE( <nMessageVariable>, <memberFxn> ) afx_msg LRESULT memberFxn(WPARAM, LPARAM);
ON_THREAD_MESSAGE( <message>, <memberFxn> ) afx_msg void memberFxn( UINT, LONG );
ON_REGISTERED_THREAD_MESSAGE( <nMessageVariable>, <memberFxn> ) afx_msg void memberFxn( UINT, LONG );


Accepted Solution

ShaunWilde earned 1200 total points
ID: 6449903
a common mistake (debug work relase not) is to use the wrong map- prototype combination
LVL 49

Expert Comment

ID: 6450076
I agree with Shaun.. check your message handlers.  When I had similar problems, it was because I had declared a handler with an improper number of arguments.  Debug version can mask that error.

Also -- just a thought-- the stack trace could be misleading because of the multithreaded aspect.  I'm not sure how, but maybe.

-- Dan

Expert Comment

ID: 6450082
How are you implementing the thread class? That is, thc class it is derived from, the mode in which the thread is created and other details..Could you post the thread code (or relevant parts of it)?

Expert Comment

ID: 6450364
I tryed to pass the HWND of main window to a thread proc and send messagess to that window in a SDI app but it did not work. But if I passed the pointer to CMainFrame class to the proc that worked. Maybe u can find it usefull too. Below is the code that creates the thread and the thread proc.

UINT fnc( LPVOID pParam )
     Sleep( 2000 );
     ((CWnd*)pParam)->ShowWindow( SW_HIDE );
     Sleep( 2000 );
     ((CWnd*)pParam)->ShowWindow( SW_SHOW );
     return 0;

void CAaaView::OnButton1()
      //Creating the thread
     AfxBeginThread( fnc, AfxGetApp()->m_pMainWnd );    

Author Comment

ID: 6450945

Yes, it was wrong prototype. I had saw it myself, but thanks anyway.

Expert Comment

ID: 6450955
It might be useful to debug the release version. This seems like a contradiction, but it works: in Project settings, on the C/C++ tab (category General), in the Debug info combo box select anything but the default "none"; and on the Link tab (general category), check the "Generate debug info" box. This gives you an opportunity to step through your code (the compiled program will be slightly larger), while all initialization, memory allocation etc. is done like in a regular release version.
If your problem is caused by a message handler with the wrong no. of parameters, you'll get an error message after exiting that message handler.

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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 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.
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
Suggested Courses

721 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