Prev: How to create a FlexGrid dynamically (using MSFlxGrd.ocx)
Next: Problems with CString (Conversion from VC6 to VC2005)
From: Andrew on 3 Feb 2006 16:48 Hi Oleg, I managed to do use WinDbg with the debug version to track the refcnt changes. And you are correct, as soon as it hits 0, there is an exception. I have 606 access to the refcnt. But everything looks ok, the refcnt just goes up and down - no-one is "trashing" the variable. Obivously there is one more decrement than increment...just tracking this will be quite a long process..nothing jumps out by inspection. One problem is that I cannot set the break point before starting the executable. How do I stop at the "entry point" before any access to the the refcnt has ever been made. 7c901230 cc int 3 0:000> ba w4 0x03609ce8 "dd 0x03609ce8 L1;kb;g" ^ Unable to set breakpoint error The system resets thread contexts after the process breakpoint so hardware breakpoints cannot be set. Go to the executable's entry point and set it then. 'ba w4 0x03609ce8 "dd 0x03609ce8 L1;kb;g"' Andrew
From: Oleg Starodumov on 4 Feb 2006 09:02 Hi Andrew, > I managed to do use WinDbg with the debug version to track the refcnt > changes. And you are correct, as soon as it hits 0, there is an > exception. I have 606 access to the refcnt. But everything looks ok, > the refcnt just goes up and down - no-one is "trashing" the variable. > Obivously there is one more decrement than increment...just tracking > this will be quite a long process..nothing jumps out by inspection. > Probably it makes sense to try to narrow down the scope a bit. For example, try to return FALSE from InitInstance() - will the problem happen then? If it does not happen, try to exit the application right after its initialization has completed. And so on, until you find the place where the problem starts happening. This might give you an idea what part of the refcnt monitoring output to look at. > One problem is that I cannot set the break point before starting the > executable. How do I stop at the "entry point" before any access to the > the refcnt has ever been made. > > 7c901230 cc int 3 > 0:000> ba w4 0x03609ce8 "dd 0x03609ce8 L1;kb;g" > ^ Unable to set breakpoint error > The system resets thread contexts after the process > breakpoint so hardware breakpoints cannot be set. > Go to the executable's entry point and set it then. > 'ba w4 0x03609ce8 "dd 0x03609ce8 L1;kb;g"' > You can use 'bp mfc71d!_DllMainCRTStartup' to break at the entry point of mfc71.dll. After the breakpoint was hit, remove it (otherwise it will be hit again e.g. when a thread starts). (If MFC is linked statically, you can use 'bp yourapp!WinMainCRTStartup' to set breakpoint at the entry point of the application (or 'bp yourapp!wWinMainCRTStartup' for Unicode builds)) Oleg
From: Andrew on 6 Feb 2006 15:44 Hi Oleg, Returning false from InitInstance has helped me narrowthis down a lot.Initially I just returned from the first line in InitInstance. No crash. So I moved the return FALSE; down my InitInstance until the crash occured and I discovered I do NOT get the crash until I return FALSE in InitInstance just after creating my MainFrame. Now here is the weird part... I thought I would have this nailed so I then set the break on the write to the refcnt. But you will see from the debug output below, that it appears the refcnt goes from 3 to 0 without triggering the breakpoint??? 0:000> bp mfc71d!_DllMainCRTStartup 0:000> g Starting to track Class instances ModLoad: 042a0000 0461f000 D:\Program Files\Intel\MKL\8.0.1\ia32\bin\mkl_p4p.dll ModLoad: 773d0000 774d2000 D:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll Breakpoint 0 hit eax=01c8fa7c ebx=034d8120 ecx=00003687 edx=7c90eb94 esi=01c8fa04 edi=00000001 eip=034d8120 esp=01c8f9f4 ebp=01c8fa10 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00200202 MFC71D!_DllMainCRTStartup: 034d8120 55 push ebp 0:000> ba w4 0x03609ce8 "dd 0x03609ce8 L1;kb;g" 0:000> g 03609ce8 00000002 ChildEBP RetAddr Args to Child 01c8f978 0350c30b 03609cd8 01c8f98c 0350c2ed MFC71D!ATL::CNilStringData::CNilStringData+0x1a 01c8f984 0350c2ed 01c8f994 02351d48 01c8f9a4 MFC71D!CAfxStringMgr::CAfxStringMgr+0x1b 01c8f98c 02351d48 01c8f9a4 034d80a3 03603008 MFC71D!operator>><wchar_t,StrTraitMFC_DLL<wchar_t,ATL::ChTraitsCRT<wchar_t> > >+0x18d 01c8f994 034d80a3 03603008 03603188 01c8f9f0 MSVCR71D!_initterm+0x18 01c8f9a4 034d81ba 03420000 00000001 01c8fd30 MFC71D!_CRT_INIT+0xa3 01c8f9f0 7c9011a7 03420000 00000001 01c8fd30 MFC71D!_DllMainCRTStartup+0x9a 01c8fa10 7c91cbab 034d8120 03420000 00000001 ntdll!LdrpCallInitRoutine+0x14 01c8fb18 7c92173e 01c8fd30 7fffe000 7ffff000 ntdll!LdrpRunInitializeRoutines+0x344 01c8fc94 7c921639 01c8fd30 7c900000 01c8fce0 ntdll!LdrpInitializeProcess+0x1131 01c8fd1c 7c90eac7 01c8fd30 7c900000 00000000 ntdll!_LdrpInitialize+0x183 00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7 03609ce8 00000003 ChildEBP RetAddr Args to Child 01c8f908 0350bee2 03609cd8 01c8f924 0345a2ac MFC71D!ATL::CStringData::AddRef+0x3e 01c8f914 0345a2ac 0360bbf4 01c8f928 01c8f934 MFC71D!CAfxStringMgr::GetNilString+0x12 01c8f924 0345b0c5 03609cd8 0360bbf4 01c8f94c MFC71D!ATL::CSimpleStringT<char,1>::CSimpleStringT<char,1>+0x3c 01c8f934 0345eedf 0360bbec 01c8f960 035d9a63 MFC71D!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > >::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> > >+0x15 01c8f94c 0345f258 00000000 0360bbec 01c8f978 MFC71D!CSyncObject::CSyncObject+0x3f 01c8f96c 0357c301 0360bbd0 01c8f9e0 035dcc28 MFC71D!CCriticalSection::CCriticalSection+0x28 01c8f984 0358e9fd 01c8f994 02351d48 01c8f9a4 MFC71D!CSessionMapPtrToPtr::CSessionMapPtrToPtr+0x41 01c8f98c 02351d48 01c8f9a4 034d80a3 03603070 MFC71D!CGopherFileFind::GetRuntimeClass+0x1d 01c8f994 034d80a3 03603070 03603188 01c8f9f0 MSVCR71D!_initterm+0x18 01c8f9a4 034d81ba 03420000 00000001 01c8fd30 MFC71D!_CRT_INIT+0xa3 01c8f9f0 7c9011a7 03420000 00000001 01c8fd30 MFC71D!_DllMainCRTStartup+0x9a 01c8fa10 7c91cbab 034d8120 03420000 00000001 ntdll!LdrpCallInitRoutine+0x14 01c8fb18 7c92173e 01c8fd30 7fffe000 7ffff000 ntdll!LdrpRunInitializeRoutines+0x344 01c8fc94 7c921639 01c8fd30 7c900000 01c8fce0 ntdll!LdrpInitializeProcess+0x1131 01c8fd1c 7c90eac7 01c8fd30 7c900000 00000000 ntdll!_LdrpInitialize+0x183 00000000 00000000 00000000 00000000 00000000 ntdll!KiUserApcDispatcher+0x7 ModLoad: 5d360000 5d36e000 D:\WINDOWS\system32\MFC71ENU.DLL ModLoad: 5ad70000 5ada8000 D:\WINDOWS\system32\uxtheme.dll VA One Initializing ...ModLoad: 732e0000 732e5000 D:\WINDOWS\system32\RICHED32.DLL ModLoad: 74e30000 74e9c000 D:\WINDOWS\system32\RICHED20.dll ModLoad: 04ba0000 04d0f000 D:\WINDOWS\system32\nview.dll ModLoad: 76bf0000 76bfb000 D:\WINDOWS\system32\PSAPI.DLL ModLoad: 77690000 776b1000 D:\WINDOWS\system32\NTMARTA.DLL ModLoad: 76f60000 76f8c000 D:\WINDOWS\system32\WLDAP32.dll ModLoad: 71bf0000 71c03000 D:\WINDOWS\system32\SAMLIB.dll ModLoad: 04d80000 04d95000 D:\WINDOWS\system32\nvwddi.dll Warning: no shared menu for document template #129. Warning: no shared menu for document template #129. Warning: Destroying non-NULL m_pMainWnd The number of objects in CGXCaptiveManager is: 0 HEAP[VAOne.exe]: Invalid Address specified to RtlValidateHeap( 03B40000, 03609CBC ) (580.ad8): Break instruction exception - code 80000003 (first chance) eax=03609cb4 ebx=03609cb4 ecx=7c91eb05 edx=01c8faf6 esi=03b40000 edi=03b40000 eip=7c901230 esp=01c8fcfc ebp=01c8fd00 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202 ntdll!DbgBreakPoint: 7c901230 cc int 3 *** WARNING: Unable to verify checksum for VAOne.exe 0:000> dd 0x03609ce8 L1 03609ce8 00000000
From: Oleg Starodumov on 7 Feb 2006 03:43 > Now here is the weird part... I thought I would have this nailed so I > then set the break on the write to the refcnt. But you will see from > the debug output below, that it appears the refcnt goes from 3 to 0 > without triggering the breakpoint??? > Most likely because I made a mistake referring you to mfc71d!_DllMainCRTStartup only. The thread context will be reset after that, so you need one more breakpoint - at yourapp!WinMainCRTStartup, and at that breakpoint you should run 'ba' command again to reenable the data breakpoint at the refcounter. Oleg
From: Andrew on 7 Feb 2006 12:27
Hi Oleg, I found the bug! It was in some third-party code ( Objective Toolkit), in a class SECStatusBar that is a replacement for CStatusBar. They had code that worked in prior versions of MFC, but causes the problem in MFC 7. I cannot thank you enough for your help! I learnt how to use WinDbg, which is a very useful tool. BOOL SECStatusBar::AllocElements(int nElements, int cbElement) { // destruct old elements AFX_STATUSPANE* pSBP = _GetPanePtr(0); for (int i = 0; i < m_nCount; i++) { pSBP->strText.~CString(); ++pSBP; } // allocate new elements if (!SECControlBar::AllocElements(nElements, cbElement)) return FALSE; /* // OLD code that works in MFC prior to 7 // construct new elements pSBP = _GetPanePtr(0); CString emptyString(""); for (i = 0; i < m_nCount; i++) { memcpy(&pSBP->strText, &emptyString, sizeof(CString)); ++pSBP; } */ // construct new elements pSBP = _GetPanePtr(0); for (i = 0; i < m_nCount; i++) { #pragma push_macro("new") #undef new new( &pSBP->strText ) CString; #pragma pop_macro("new") ++pSBP; } return TRUE; } |