"has triggered a breakpoint" error when closing my SDI app using the CLOSE button.

Hi,

I know these errors can be put down to bad pointers etc, but I've been through all my code and cannot for the life of me work out why this is happening.

I have an SDI MFC app (written in VS2005) and when I close it via the 'close' button it always triggers breakpoints on exit (_after_ the onclose method in CMainFrame has been called and completed).

However, it closed absolutely fine with no errors when I use File>Exit or double click the top left of the window to close it.

Please help, is there a simple workaround for this so I can capture the close button click and make it do exactly what file>exit does instead, or are there any other quick suggestions as to what may be causing it?

Thanks in advance!

Chris J
chrispauljarramAsked:
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.

pgnatyukCommented:
with BoundChecker you can find the leak.
Put breakpoints into all Close and Destroy handlers to see that it works; and works only once; check that your windows do not try to handle something else after the close message.
0
chrispauljarramAuthor Commented:
Hi,

I don't have BoundChecker unfortautnely and can't find an evaluation copy, any other suggestions?

Cheers,
Chris J
0
pgnatyukCommented:
when the app stopped on the berakpoint, you can continue, right?
Than in the Output window you see a memory dump or a warning message?
Please take a look here:
http://msdn.microsoft.com/en-us/library/974tc9t1(VS.71).aspx
http://msdn.microsoft.com/en-us/library/k70yt3e2(VS.71).aspx
http://msdn.microsoft.com/en-us/library/e5ewb1h3(VS.80).aspx
I know, what you're going to say. :)
 _CRTDBG_MAP_ALLOC helped me many times.
Purify+? I know it's all not for free.
 
0
Become a Certified Penetration Testing Engineer

This CPTE Certified Penetration Testing Engineer course covers everything you need to know about becoming a Certified Penetration Testing Engineer. Career Path: Professional roles include Ethical Hackers, Security Consultants, System Administrators, and Chief Security Officers.

itsmeandnobodyelseCommented:
>>>> and when I close it via the 'close' button

Can you post the code for OnClose() ?

The easiest closing is to post a WM_CLOSE message to the mainframe window:

     AfxGetMainWnd()->PostMessage(WM_CLOSE);

It should have the same effect than with using the 'x' or File->Exit
0
chrispauljarramAuthor Commented:
itsmeandnobodyelse:

Clearly File->Exit and using the 'X' do different things as stated in the question (which I'm not sure you understood?)

Thanks,
Chris J
0
pgnatyukCommented:
When the user presses "File->Exit" the message comes to the main frame. Right? Probably you have something like OnFileExit method.
When the user uses 'X', the message also comes to the main frame, but this time works OnClose method. Or you don't have this method?
If you don't have, let's add it. Here we will do the same as in OnFileExit. Is it possible?
 
0
itsmeandnobodyelseCommented:
>>>> Clearly File->Exit and using the 'X' do different
Thank you. Yes, I thought you had a separate Close button in some form which didn't work.

So your problem is that using the 'x' doesn't do the same as double-clicking on the application icon top-left?

If so, the mainframe onclose ran in some issues which do not occur when the application was closed rather the frame.

What is strange, that File->Exit also should send a WM_CLOSE message to the main window (what is the mainframe in a SDI). So, the CMainFrame::OnClose should be called in any case.

Can you post that function? And tell where the user breaks happen?

If the OnClose wasn't called when closing with File-Exit you could do - as a workaround not as a solution -
 

    (MyApp*)AfxGetApp())->OnFileExit();

in CMainFrame::OnClose and return after that. Note, that would give an infinite loop if OnClose would be called later.
0
chrispauljarramAuthor Commented:
Hi,

Thanks again for the suggestions - the OnClose() method is always called whether I use the 'x' button or file>exit, so you are right there.  The user breaks always happen at the end of the function when I call back up to CWnd::OnClose() after doing my things.  I do a bit of cleanup in the close method as well as iterate through 'User' objects which I ask one by one if the user wants to save (however the fault still ocurrs even if the userlist is empty).

The entire method body is:

void CMainFrame::OnClose()
{
      int userCount = m_pUsers->GetCount();

      for(int i = 0; i < userCount; i++)
      {
            CUser* user = (CUser*) m_pUsers->GetAt(m_pUsers->FindIndex(i));

            if(user->changed)
            {
                  sprintf(cTemp, "Do you wish to save changes to %s?", m_pUserSettingsView->getCurrentUser()->name);
                  int ret = MessageBox(cTemp, "Save User", MB_ICONQUESTION | MB_YESNOCANCEL);
                  
                  if(ret == IDYES)
                  {
                        OnSaveUser();
                  }
                  else if(ret == IDCANCEL)
                  {
                        return;
                  }
            }
      }

      mainThread.exit = true;

      // Give thread time to stop before clearing up objects and closing window.
      Sleep(1000);

      if(currentGame != NULL)
      {
            currentGame->gameClosed();
      }

      delete m_pConsole;
      m_pConsole = NULL;

      OpenIniFile();
      CIniFile::DeleteSection(OPENUSERS_SECTION_NAME, INIFILE_NAME);

      int savedUserCount = 0;

      for(int i = 0; i < m_pUsers->GetCount(); i++)
      {
            CUser* user = (CUser*) m_pUsers->GetAt(m_pUsers->FindIndex(i));

            if(user->fileName != NULL)
            {
                  sprintf(cTemp, "User%d", savedUserCount);
                  savedUserCount++;
                  CIniFile::SetValue(cTemp, user->fileName, OPENUSERS_SECTION_NAME, INIFILE_NAME);
            }

            // Save in open users list for next time (if this is a saved user).

            user->Destroy();
            delete user;
            user = NULL;
      }

      m_pUsers->RemoveAll();
      delete m_pUsers;
      m_pUsers = NULL;

      for(int i = 0; i < m_pGames->GetCount(); i++)
      {
            CGame* game = (CGame*) m_pGames->GetAt(m_pGames->FindIndex(i));
            game->Destroy();
            delete game;
            game = NULL;
      }

      m_pGames->RemoveAll();
      delete m_pGames;
      m_pGames = NULL;

      for(int i = 0; i < m_pMotionDevices->GetCount(); i++)
      {
            CNSSConfiguredMotionDevice* dev = (CNSSConfiguredMotionDevice*) m_pMotionDevices->GetAt(m_pMotionDevices->FindIndex(i));
            dev->Destroy();
            delete dev;
            dev = NULL;
      }

      m_pMotionDevices->RemoveAll();
      delete m_pMotionDevices;
      m_pMotionDevices = NULL;

      for(int i = 0; i < m_pWindDevices->GetCount(); i++)
      {
            CNSSConfiguredWindDevice* dev = (CNSSConfiguredWindDevice*) m_pWindDevices->GetAt(m_pWindDevices->FindIndex(i));
            dev->Destroy();
            delete dev;
            dev = NULL;
      }

      m_pWindDevices->RemoveAll();
      delete m_pWindDevices;
      m_pWindDevices = NULL;

      _CrtDumpMemoryLeaks();
      CWnd::OnClose();
}


The
_CRTDBG_MAP_ALLOC and _CrtDumpMemoryLeaks(); define / method have helped me clean up a few strings I had lying about - however the call to _CrtDumpMemoryLeaks(); does still result in some being shown but it does not make it obvious where. The output is as follows:

Detected memory leaks!
Dumping objects ->
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {15825} normal block at 0x036A1FE0, 25 bytes long.
 Data: <  >x            > EC 97 3E 78 08 00 00 00 08 00 00 00 01 00 00 00
{1597} normal block at 0x033E8FD0, 40 bytes long.
 Data: < IG             > 20 49 47 00 00 00 00 00 01 00 00 00 00 CD CD CD
{1308} normal block at 0x035F0FE8, 20 bytes long.
 Data: < IG             > 14 49 47 00 00 00 00 00 01 00 00 00 00 CD CD CD
{205} normal block at 0x0340BBF8, 1024 bytes long.
 Data: <0 Mph           > 30 20 4D 70 68 00 CD CD CD CD CD CD CD CD CD CD
{185} client block at 0x033E2F38, subtype c0, 192 bytes long.
a CUserSettingsView object at $033E2F38, 192 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\plex.cpp(29) : {181} normal block at 0x033DAF80, 124 bytes long.
 Data: <      =     XO= > 00 00 00 00 90 AF 3D 03 00 00 00 00 58 4F 3D 03
{179} normal block at 0x033D6FE8, 16 bytes long.
 Data: <  0.00          > 20 20 30 2E 30 30 B0 00 CD CD CD CD CD CD CD CD
{178} client block at 0x033D4F58, subtype c0, 160 bytes long.
a CGameInfoView object at $033D4F58, 160 bytes long
{177} normal block at 0x033D2FF0, 12 bytes long.
 Data: <            > 00 00 00 00 00 00 00 00 16 02 00 00
{176} normal block at 0x033D0FE0, 24 bytes long.
 Data: <                > 96 00 00 00 96 00 00 00 96 00 00 00 00 00 00 00
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {172} normal block at 0x033C8FC8, 47 bytes long.
 Data: <  >x            > EC 97 3E 78 1E 00 00 00 1E 00 00 00 01 00 00 00
c:\documents and settings\chris\my documents\visual studio 2005\projects\nssdriverapp\nssdriverapp\mainfrm.cpp(56) : {169} normal block at 0x033C2BF8, 1024 bytes long.
 Data: <User0 vice3ID an> 55 73 65 72 30 00 76 69 63 65 33 49 44 00 61 6E
c:\documents and settings\chris\my documents\visual studio 2005\projects\nssdriverapp\nssdriverapp\mainfrm.cpp(21) : {168} client block at 0x033C0DE8, subtype c0, 532 bytes long.
a CMainFrame object at $033C0DE8, 532 bytes long
c:\documents and settings\chris\my documents\visual studio 2005\projects\nssdriverapp\nssdriverapp\nssdriverappdoc.cpp(16) : {167} client block at 0x033BEFA8, subtype c0, 84 bytes long.
a CNSSDriverAppDoc object at $033BEFA8, 84 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\plex.cpp(29) : {152} normal block at 0x033A0F80, 124 bytes long.
 Data: <              9 > 00 00 00 00 00 00 00 00 00 00 00 00 90 AF 39 03
{151} client block at 0x0339EFD8, subtype c0, 32 bytes long.
a CDocManager object at $0339EFD8, 32 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {150} normal block at 0x0339CF60, 154 bytes long.
 Data: <  >x            > EC 97 3E 78 89 00 00 00 89 00 00 00 01 00 00 00
c:\documents and settings\chris\my documents\visual studio 2005\projects\nssdriverapp\nssdriverapp\nssdriverapp.cpp(70) : {149} client block at 0x0339AF90, subtype c0, 108 bytes long.
a CSingleDocTemplate object at $0339AF90, 108 bytes long
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {147} normal block at 0x03396FE0, 23 bytes long.
 Data: <  >x            > EC 97 3E 78 06 00 00 00 06 00 00 00 01 00 00 00
f:\rtm\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(141) : {146} normal block at 0x03394FD8, 33 bytes long.
 Data: <  >x            > EC 97 3E 78 10 00 00 00 10 00 00 00 01 00 00 00
{145} normal block at 0x03392FE8, 20 bytes long.
 Data: <      >x  >x  >x> 04 00 00 00 00 98 3E 78 00 98 3E 78 00 98 3E 78
{144} normal block at 0x03390FD8, 32 bytes long.
 Data: <$R x     /9  O9 > 24 52 1E 78 04 00 00 00 EC 2F 39 03 E8 4F 39 03
{65} client block at 0x029A7FB8, subtype c0, 64 bytes long.
a CDynLinkLibrary object at $029A7FB8, 64 bytes long
Object dump complete.
The thread 'Win32 Thread' (0xe98) has exited with code -1 (0xffffffff).
Detected memory leaks!
Dumping objects ->
{1597} normal block at 0x033E8FD0, 40 bytes long.
 Data: < IG             > 20 49 47 00 00 00 00 00 01 00 00 00 00 CD CD CD
{1308} normal block at 0x035F0FE8, 20 bytes long.
 Data: < IG             > 14 49 47 00 00 00 00 00 01 00 00 00 00 CD CD CD
Object dump complete.
The program '[2680] NSSDriverApp.exe: Native' has exited with code 0 (0x0).


These are either in files which do not belong to me or it simply doesnt say.

Could this be the problem?  Thanks for the useful information on the debug stack etc btw pgnatyuk, I'll have a good root through that when I get some time, maybe it will help shed further light on what is going on here.

Thanks :)
Chris J
0
itsmeandnobodyelseCommented:
>>>> CWnd::OnClose()

You need to call CFrameWnd::OnClose();

I don't know whether that will solve the user breaks but calling CWnd::Close most likely was skipping some OnClose functions between (I will check that).

>>>> _CrtDumpMemoryLeaks();

The explicit call of that function will bring some leaks which are not really leaks but heap allocations made by static class objects. These were freed when the application terminated but not at this time. Also allocation made by the app class are reported as leaks.

0
pgnatyukCommented:
Hi Chris
it says a lot. But actually you need to call this report function somewhere in ExitInstance.
Probably you have a lot of CString objects? I can be wrong, but somehow few times I fixed problems in my apps that looked like you posted now.
In my case we had few CString object declared in the cpp-files - static variables. So I just declared them as class members and cleared in the class destructors.
In your case it looks like a child window was not closed. Can you check it? Somehow stop the app before the closing?
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
pgnatyukCommented:
CWnd::OnClose(); - this line. Maybe it should be CFrame::OnClose()?
0
itsmeandnobodyelseCommented:
>>>> CWnd::OnClose most likely was skipping some OnClose functions between (I will check that).

Yes, the CFrameWnd::OnClose has an implementation which you skipped by calling CWnd::OnClose

0
itsmeandnobodyelseCommented:
>>>> mainfrm.cpp(56) : {169} normal block at 0x033C2BF8, 1024 bytes long.
 Data: <User0 vice3ID an> 55 73 65 72 30 00 76 69 63 65 33 49 44 00 61 6E
>>>> nssdriverapp\nssdriverapp\mainfrm.cpp(21) : {168} client block at 0x033C0DE8, subtype c0, 532 bytes long.
a CMainFrame object at $033C0DE8, 532 bytes long
>>>> nssdriverapp\nssdriverapp\nssdriverappdoc.cpp(16) : {167} client block at 0x033BEFA8, subtype c0, 84 bytes long.

All these are normal allocations of class members where the destructor did not yet run.

You only should bother for leaks reported by the debugger at end of program.


0
chrispauljarramAuthor Commented:
Thanks
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.