From: Hector Santos on
Rusian,

Change the lines to:

char buffer[128] = { 0 };
int nLen = ::GetWindowTextLength(list_custom_indmin.m_hWnd);
::GetWindowText(list_custom_indmin.m_hWnd, buffer, 128);

to:

CString sBuffer;
list_custom_indmin.GetWindowText(&sBuffer);

and that should work.

Ruslan Shcherbatyuk wrote:

> BTW, looks like number of bytes returned by ::GetWindowText is about exactly
> 2 times bigger than ::GetWindowTextLen had returned. My application is
> non-unicode, may be CVSListBox is somehow incompatible with non-unicode apps
> or I forget to do some 'special' initialization, like InitCommonCotrols or
> like this?
>
> Anyway I can use it in my non-unicode app by applying ctrl.SetWindowText("")
> before its OnPaint hander inside of OnInitDialog of hosting PropertyPage.
>
> "Joseph M. Newcomer" wrote:
>
>> See below...
>> On Mon, 19 Apr 2010 14:41:01 -0700, Ruslan Shcherbatyuk
>> <RuslanShcherbatyuk(a)discussions.microsoft.com> wrote:
>>
>>> New information and I still have no idea what is the problem or how to find it.
>>> I had used OnIdle and _heapchk() and assertion not happens.
>>>
>>> Below is a callstack of heap corruption moment:
>>>
>>>> ComputerZal.exe!_free_dbg_nolock(void * pUserData=0x02183d28, int nBlockUse=0x00000001) Line 1376 + 0x3b bytes C++
>>> ComputerZal.exe!_free_dbg(void * pUserData=0x02183d28, int
>>> nBlockUse=0x00000001) Line 1265 + 0xd bytes C++
>>> ComputerZal.exe!free(void * pUserData=0x02183d28) Line 49 + 0xb bytes C++
>>> ComputerZal.exe!CAfxStringMgr::Free(ATL::CStringData * pData=0x02183d28)
>>> Line 169 + 0x9 bytes C++
>>> ComputerZal.exe!ATL::CStringData::Release() Line 116 + 0x17 bytes C++
>>> ComputerZal.exe!ATL::CSimpleStringT<char,0>::~CSimpleStringT<char,0>()
>>> Line 289 C++
>>> ComputerZal.exe!ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char>
>>>>> ::~CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >() Line 1213
>>> + 0x8 bytes C++
>>> ComputerZal.exe!CVSListBoxBase::OnPaint() Line 333 + 0xf bytes C++
>>> ComputerZal.exe!CWnd::OnWndMsg(unsigned int message=0x0000000f, unsigned
>>> int wParam=0x00000000, long lParam=0x00000000, long * pResult=0x001272c8)
>>> Line 2354 C++
>>>
>>> The problem is in destructor of CString object of CVSListBoxBase::OnPaint()
>>> method:
>>>
>>> ............
>>> CString strCaption;
>>>
>>> if (m_bDefaultCaption)
>>> {
>>> GetWindowText(strCaption); // ************
>> ****
>> This cannot fail. If it is failing, you already have memory damage.
>> ****
>>> }
>>> else
>>> {
>>> strCaption = m_strCaption;
>>> }
>>>
>>> dc.DrawText(strCaption, rectText, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
>>>
>>> if (pOldFont != NULL)
>>> {
>>> dc.SelectObject(pOldFont);
>>> }
>>> // HERE !!!!!!!!!!!!!!!!!!!!!!!!
>>> }
>>>
>>> Heap corruption appears inside of GetWindowText(strCaption); // ************
>>>
>>> void CWnd::GetWindowText(CString& rString) const
>>> {
>>> ASSERT(::IsWindow(m_hWnd));
>>>
>>> #ifndef _AFX_NO_OCC_SUPPORT
>>> if (m_pCtrlSite == NULL)
>>> {
>>> #endif
>>> int nLen = ::GetWindowTextLength(m_hWnd);
>>> ::GetWindowText(m_hWnd, rString.GetBufferSetLength(nLen), nLen+1);
>>>
>>> nLen is returned 0x16, and buffer is allocated of 0x16 bytes but buffer is
>>> actually filled with much more bytes in call to ::GetWindowText.
>> ****
>> And you know this how? Note that ::GetWindowText takes a maximum buffer length and will
>> not fill in more characters than the specified length.
>> ****
>>> I reproduced this behavior at the end of OnInitDialog of page where
>>> CVSListBox is placed:
>>>
>>> char buffer[128] = { 0 };
>> ****
>> First, the use of char is wrong, and the use of a buffer of a fixed size (like 128)
>> represents Worst Practice. Why did you not use CString here?
>> ****
>>> int nLen = ::GetWindowTextLength(list_custom_indmin.m_hWnd);
>>> ::GetWindowText(list_custom_indmin.m_hWnd, buffer, 128);
>>>
>>> How the buffer is look like before getting of nLen=0x16 (actually it
>>> received much more bytes):
>>>
>>> 0x001263E4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x001263F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x00126408 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x0012641A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x0012642C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x0012643E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x00126450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>>
>>> and after:
>>>
>>> 00 42 65 7a 4d 46 43 56 53 4c 69 73 74 42 6f 78 00 bf .BezMFCVSListBox.?
>>> 0x001263F6 4f 80 89 e3 37 7e 4f e3 37 7e 04 00 00 80 f0 69 12 00
>>> O?.?7~O?7~...??i..
>>> 0x00126408 50 65 12 00 04 6a 12 00 00 00 00 00 00 00 00 00 00 00
>>> Pe...j............
>>> 0x0012641A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x0012642C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x0012643E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>>> 0x00126450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>>> ..................
>> ****
>> I've never seen a failure like this on GetWindowText. Essentially, it got a 0-length
>> string (the initial NUL character), and I have no idea why it would retrieve anything
>> else, but it shouldn't matter because it did not overrun the buffer
>>
>> I wonder: did someone implement a WM_GETTEXT handler for CVSListBox that is doing the
>> wrong thing? That's the first guess I would make. I'd suggest looking at the CVSListBox
>> source code to see what handlers are in its Message Map, and if there is a WM_GETTEXT, I'd
>> read its code to make sure the programmer didn't screw up big time. THat's how I'd start
>> to do the analysis.
>> joe
>> ****
>>> As you can see we received much more than 0x16 bytes.
>> ****
>> Looks like a serious error in the CVSListBox code to me
>> ****
>>> I also put _heapchk() at the end of OnInitDialog() (just before appearing of
>>> ON_PAINT of CVSListBox) and nothing is corrupted inside of heap. There are
>>> also no any threads that can corrupt something and, as I told before
>>> everything is working fine inside of x64 Win 7 where VS2010 is installed.
>> ****
>> Threads don't matter at all in this case. In fact, if there is an error of the kind I
>> described, it can happen in a single-threaded app.
>> ****
>>> I'm using remote debugging to observe bug on destination VMWare PC with
>>> WinXP x86 installed.
>>>
>>> Any recomendations? What can I try next?
>> ***
>> See above. There are a scary number of tools between you and the application, and that
>> makes me worry that anything might be broken.
>> ****
>>> Is it possible that Win7 PC has no this bug because of VS 2010 installation
>>> (may be it has other MFC/COMCTL32 dll's)? Although I am using statical MFC
>>> linking to executable.
>> ****
>> I'd do a LOT of single-stepping, and, as I said, I'd be very suspect of the CVSListBox
>> code.
>>
>> But what you are seeing is supposed to be impossible. Because it has returned a string of
>> 0 length, there should be no other characters in the string.
>> joe
>> ****
>>> I will wait for other recomendations and hope that this message has more
>>> information.
>>> "Ruslan Shcherbatyuk" wrote:
>>>
>>>> Thank you for your comments and sorry for using wrong 'crash' keyword, I will
>>>> do more deep debugging using OnIdle heap check technik and will report about
>>>> results as soon as I understand something.
>>>>
>>>> "Joseph M. Newcomer" wrote:
>>>>
>>>>> (a) My program reports an unhandled exception 0xC0000005 in the function XXXXXX at the
>>>>> following line:
>>>>> <source code here>
>>>>> I examined the variables, and the value being passed in is 0xCCCCCD8.
>>>>>
>>>>> [dead giveaway: uninitialized local pointer variable]
>>>>>
>>>>> (b) My program, which is running under VS2008 without SP1, gave an assertion failure on
>>>>> line NNNN or file XXXXXX.cpp (here is the function). I have indicated which of the
>>>>> assertions failed. When I examined the value with the debugger, it was 0 (NULL). The
>>>>> callback trace to my code is also shown, and the source line from my code is indicated
>>>>> below
>>>>> Something * v;
>>>>> ...stuff here...
>>>>> v = SomeFunction(...);
>>>>> SomeOtherFunction(v); <<== this is the last line issued before the assertion
>>>>> failure
>>>>>
>>>>> [dead giveaway: the SomeFunction failed, returned NULL as documented, and you failed to
>>>>> test for this condition before using the value]
>>>>>
>>>>> (c) My program, which is running under VS2008 SP1, gave an unhandled exception 0xC80000003
>>>>> at the following line in the storage allocator:
>>>>>
>>>>> [dead giveaway: attempting to free something twice, storage damage due to mishandled
>>>>> bounds on an array store or fetch, etc., especially if the values are given! The source
>>>>> line usually has comments indicating the reason for the failure, and from this we can
>>>>> usually make a pretty good guess]
>>>>>
>>>>> These are meaningful resports. All of the suggestions you give below are equivalent to
>>>>> the word "crash" in terms of their useful content.
>>>>>
>>>>> Note in the definition you give, a "crash" of a computer is rather different than a
>>>>> "crash" of a program under development, and even then the description of "crash" is for
>>>>> people like my mother, who can't tell an unhandled kernel exception from a heap
>>>>> corruption; all she knows is her screen turned blue and the letter she was writing is
>>>>> lost. I expect something a bit more coherent from someone who claims to be a programmer!
>>>>>
>>>>> Note that all the definitions describe different conditions, which would require different
>>>>> actions to handle. A non-responding program is quite a different problem from one which
>>>>> has taken an unhandled exception, or one which has taken an assertion failure. Again, the
>>>>> audiences are different; programmers are assumed to be capable of distinguishing all these
>>>>> causes in a report and providing maximum information to allow diagnosis of the problem by
>>>>> another programmer. So if I report that my program isn't running correctly, what,
>>>>> exactly, do you think you can do to help me? But if I specifically say what I am
>>>>> observing, and, as a programmer, tell you the values of the variables involved, I am
>>>>> giving you the critical information you need to help me. This is a programmers'
>>>>> newsgroup; I expect a programmer's description of the problem, not the description my
>>>>> mother would give (she called me up once and said her computer said it had done something
>>>>> illegal, and should she be concerned? But she was 85 at the time). So when a person who
>>>>> claims to be a "programmer" says "my program crashed" I expect them to have the minimum
>>>>> capability of reporting EXACTLY what happened in terms of the executing code!
>>>>> joe
>>>>>
>>>>>
>>>>> On Mon, 19 Apr 2010 13:15:47 -0400, Hector Santos <sant9442(a)nospam.gmail.com> wrote:
>>>>>
>>>>>> Ok, what do you want to say?
>>>>>>
>>>>>> "My program stopped working."
>>>>>> "My program popped up GPF box"
>>>>>> "My program faulted"
>>>>>> "My program abend"
>>>>>> "My program aborted"
>>>>>> "My program refused to run."
>>>>>> "My program quit for some reason."
>>>>>>
>>>>>> Crash is not suppose to describe what exactly happen. Only that
>>>>>> ultimate outcome has occurred.
>>>>>>
>>>>>> Google:
>>>>>>
>>>>>> define: crash
>>>>>>
>>>>>> * stop operating; "My computer crashed last night";
>>>>>> "The system goes down at least once a week"
>>>>>>
>>>>>> Webster:
>>>>>>
>>>>>> d) of a computer system, component, or program : to suffer a
>>>>>> sudden major failure usually with attendant loss of data
>>>>>>
>>>>>> http://en.wikipedia.org/wiki/Crash
>>>>>>
>>>>>> # Crash (computing), a condition where a program ceases to respond
>>>>>>
>>>>>> I actually don't like the Wikipedia insert. It should say:
>>>>>>
>>>>>> # Crash (computing), a condition where a program no longer
>>>>>> operates correctly or continues to run.
>>>>>>
>>>>>> It would be able to the user or developer to find out the reason why
>>>>>> their program crashed (aborted, abend, faulted, stop running, etc,
>>>>>> pick up).
>>>>>>
>>>>>> --
>>>>>>
>>>>>> Joseph M. Newcomer wrote:
>>>>>>
>>>>>>> I am SERIOUSLY trying to make people stop using the word "crash" when they do not describe
>>>>>>> WHAT happened. Sadly, too many people confuse "assertion failure" with "crash" and NONE
>>>>>>> of them actually spend any time in the debugger trying to figure out what went wrong.
>>>>>>> joe
>>>>>>>
>>>>>>> On Mon, 19 Apr 2010 11:19:01 -0400, Hector Santos <sant9442(a)nospam.gmail.com> wrote:
>>>>>>>
>>>>>>>> Joseph M. Newcomer wrote:
>>>>>>>>
>>>>>>>>> This doesn't work because there is no way to "walk around" an instance of heap damage.
>>>>>>>>>
>>>>>>>>> The analogy is intended to be simple, to cover the simple case. You are tryiing to
>>>>>>>>> stretch it by bringing in mechanisms that simply do not exist. There are really only two
>>>>>>>>> options: fall into the hole, or know that there is an open manhole somewhere on the street
>>>>>>>>> into which you may or may not fall. That's all the mechanisms that exist.
>>>>>>>>>
>>>>>>>>> The point of the analogy is to indicate the temporal separation between the event and its
>>>>>>>>> detection; it is a common confusion to believe that the even that detected the problem is
>>>>>>>>> the event that caused the problem.
>>>>>>>> I don't disagree.
>>>>>>>>
>>>>>>>> My point is that people must have the understanding of its existence
>>>>>>>> and how it plays a role before they can make any conclusion or
>>>>>>>> intelligent guess work at problem detection and resolution.



--
HLS
From: David Lowndes on
>BTW, looks like number of bytes returned by ::GetWindowText is about exactly
>2 times bigger than ::GetWindowTextLen had returned.

There are some quirks with GetWindowTextLength - see the remarks in
the MSDN documentation.

Dave
From: Ruslan Shcherbatyuk on
Hector, this 128 is just small test code for reproducing of error OUTSIDE of
MFC internals (inside of my OnInitDialog), just for my convenient
reproducing. If I remove this code at all the same will be inside of MFC
internals, the difference, that in this code I can clearly observe buffer
changes (there are 44 bytes that is written instead of 22).
So that should not work...

"Hector Santos" wrote:

> Rusian,
>
> Change the lines to:
>
> char buffer[128] = { 0 };
> int nLen = ::GetWindowTextLength(list_custom_indmin.m_hWnd);
> ::GetWindowText(list_custom_indmin.m_hWnd, buffer, 128);
>
> to:
>
> CString sBuffer;
> list_custom_indmin.GetWindowText(&sBuffer);
>
> and that should work.
>
> Ruslan Shcherbatyuk wrote:
>
> > BTW, looks like number of bytes returned by ::GetWindowText is about exactly
> > 2 times bigger than ::GetWindowTextLen had returned. My application is
> > non-unicode, may be CVSListBox is somehow incompatible with non-unicode apps
> > or I forget to do some 'special' initialization, like InitCommonCotrols or
> > like this?
> >
> > Anyway I can use it in my non-unicode app by applying ctrl.SetWindowText("")
> > before its OnPaint hander inside of OnInitDialog of hosting PropertyPage.
> >
> > "Joseph M. Newcomer" wrote:
> >
> >> See below...
> >> On Mon, 19 Apr 2010 14:41:01 -0700, Ruslan Shcherbatyuk
> >> <RuslanShcherbatyuk(a)discussions.microsoft.com> wrote:
> >>
> >>> New information and I still have no idea what is the problem or how to find it.
> >>> I had used OnIdle and _heapchk() and assertion not happens.
> >>>
> >>> Below is a callstack of heap corruption moment:
> >>>
> >>>> ComputerZal.exe!_free_dbg_nolock(void * pUserData=0x02183d28, int nBlockUse=0x00000001) Line 1376 + 0x3b bytes C++
> >>> ComputerZal.exe!_free_dbg(void * pUserData=0x02183d28, int
> >>> nBlockUse=0x00000001) Line 1265 + 0xd bytes C++
> >>> ComputerZal.exe!free(void * pUserData=0x02183d28) Line 49 + 0xb bytes C++
> >>> ComputerZal.exe!CAfxStringMgr::Free(ATL::CStringData * pData=0x02183d28)
> >>> Line 169 + 0x9 bytes C++
> >>> ComputerZal.exe!ATL::CStringData::Release() Line 116 + 0x17 bytes C++
> >>> ComputerZal.exe!ATL::CSimpleStringT<char,0>::~CSimpleStringT<char,0>()
> >>> Line 289 C++
> >>> ComputerZal.exe!ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char>
> >>>>> ::~CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >() Line 1213
> >>> + 0x8 bytes C++
> >>> ComputerZal.exe!CVSListBoxBase::OnPaint() Line 333 + 0xf bytes C++
> >>> ComputerZal.exe!CWnd::OnWndMsg(unsigned int message=0x0000000f, unsigned
> >>> int wParam=0x00000000, long lParam=0x00000000, long * pResult=0x001272c8)
> >>> Line 2354 C++
> >>>
> >>> The problem is in destructor of CString object of CVSListBoxBase::OnPaint()
> >>> method:
> >>>
> >>> ............
> >>> CString strCaption;
> >>>
> >>> if (m_bDefaultCaption)
> >>> {
> >>> GetWindowText(strCaption); // ************
> >> ****
> >> This cannot fail. If it is failing, you already have memory damage.
> >> ****
> >>> }
> >>> else
> >>> {
> >>> strCaption = m_strCaption;
> >>> }
> >>>
> >>> dc.DrawText(strCaption, rectText, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
> >>>
> >>> if (pOldFont != NULL)
> >>> {
> >>> dc.SelectObject(pOldFont);
> >>> }
> >>> // HERE !!!!!!!!!!!!!!!!!!!!!!!!
> >>> }
> >>>
> >>> Heap corruption appears inside of GetWindowText(strCaption); // ************
> >>>
> >>> void CWnd::GetWindowText(CString& rString) const
> >>> {
> >>> ASSERT(::IsWindow(m_hWnd));
> >>>
> >>> #ifndef _AFX_NO_OCC_SUPPORT
> >>> if (m_pCtrlSite == NULL)
> >>> {
> >>> #endif
> >>> int nLen = ::GetWindowTextLength(m_hWnd);
> >>> ::GetWindowText(m_hWnd, rString.GetBufferSetLength(nLen), nLen+1);
> >>>
> >>> nLen is returned 0x16, and buffer is allocated of 0x16 bytes but buffer is
> >>> actually filled with much more bytes in call to ::GetWindowText.
> >> ****
> >> And you know this how? Note that ::GetWindowText takes a maximum buffer length and will
> >> not fill in more characters than the specified length.
> >> ****
> >>> I reproduced this behavior at the end of OnInitDialog of page where
> >>> CVSListBox is placed:
> >>>
> >>> char buffer[128] = { 0 };
> >> ****
> >> First, the use of char is wrong, and the use of a buffer of a fixed size (like 128)
> >> represents Worst Practice. Why did you not use CString here?
> >> ****
> >>> int nLen = ::GetWindowTextLength(list_custom_indmin.m_hWnd);
> >>> ::GetWindowText(list_custom_indmin.m_hWnd, buffer, 128);
> >>>
> >>> How the buffer is look like before getting of nLen=0x16 (actually it
> >>> received much more bytes):
> >>>
> >>> 0x001263E4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x001263F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x00126408 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x0012641A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x0012642C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x0012643E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x00126450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>>
> >>> and after:
> >>>
> >>> 00 42 65 7a 4d 46 43 56 53 4c 69 73 74 42 6f 78 00 bf .BezMFCVSListBox.?
> >>> 0x001263F6 4f 80 89 e3 37 7e 4f e3 37 7e 04 00 00 80 f0 69 12 00
> >>> O?.?7~O?7~...??i..
> >>> 0x00126408 50 65 12 00 04 6a 12 00 00 00 00 00 00 00 00 00 00 00
> >>> Pe...j............
> >>> 0x0012641A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x0012642C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x0012643E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >>> 0x00126450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> >>> ..................
> >> ****
> >> I've never seen a failure like this on GetWindowText. Essentially, it got a 0-length
> >> string (the initial NUL character), and I have no idea why it would retrieve anything
> >> else, but it shouldn't matter because it did not overrun the buffer
> >>
> >> I wonder: did someone implement a WM_GETTEXT handler for CVSListBox that is doing the
> >> wrong thing? That's the first guess I would make. I'd suggest looking at the CVSListBox
> >> source code to see what handlers are in its Message Map, and if there is a WM_GETTEXT, I'd
> >> read its code to make sure the programmer didn't screw up big time. THat's how I'd start
> >> to do the analysis.
> >> joe
> >> ****
> >>> As you can see we received much more than 0x16 bytes.
> >> ****
> >> Looks like a serious error in the CVSListBox code to me
> >> ****
> >>> I also put _heapchk() at the end of OnInitDialog() (just before appearing of
> >>> ON_PAINT of CVSListBox) and nothing is corrupted inside of heap. There are
> >>> also no any threads that can corrupt something and, as I told before
> >>> everything is working fine inside of x64 Win 7 where VS2010 is installed.
> >> ****
> >> Threads don't matter at all in this case. In fact, if there is an error of the kind I
> >> described, it can happen in a single-threaded app.
> >> ****
> >>> I'm using remote debugging to observe bug on destination VMWare PC with
> >>> WinXP x86 installed.
> >>>
> >>> Any recomendations? What can I try next?
> >> ***
> >> See above. There are a scary number of tools between you and the application, and that
> >> makes me worry that anything might be broken.
> >> ****
> >>> Is it possible that Win7 PC has no this bug because of VS 2010 installation
> >>> (may be it has other MFC/COMCTL32 dll's)? Although I am using statical MFC
> >>> linking to executable.
> >> ****
> >> I'd do a LOT of single-stepping, and, as I said, I'd be very suspect of the CVSListBox
> >> code.
> >>
> >> But what you are seeing is supposed to be impossible. Because it has returned a string of
> >> 0 length, there should be no other characters in the string.
> >> joe
> >> ****
> >>> I will wait for other recomendations and hope that this message has more
> >>> information.
> >>> "Ruslan Shcherbatyuk" wrote:
> >>>
> >>>> Thank you for your comments and sorry for using wrong 'crash' keyword, I will
> >>>> do more deep debugging using OnIdle heap check technik and will report about
> >>>> results as soon as I understand something.
> >>>>
> >>>> "Joseph M. Newcomer" wrote:
> >>>>
> >>>>> (a) My program reports an unhandled exception 0xC0000005 in the function XXXXXX at the
> >>>>> following line:
> >>>>> <source code here>
> >>>>> I examined the variables, and the value being passed in is 0xCCCCCD8.
> >>>>>
> >>>>> [dead giveaway: uninitialized local pointer variable]
> >>>>>
> >>>>> (b) My program, which is running under VS2008 without SP1, gave an assertion failure on
> >>>>> line NNNN or file XXXXXX.cpp (here is the function). I have indicated which of the
> >>>>> assertions failed. When I examined the value with the debugger, it was 0 (NULL). The
> >>>>> callback trace to my code is also shown, and the source line from my code is indicated
> >>>>> below
> >>>>> Something * v;
> >>>>> ...stuff here...
> >>>>> v = SomeFunction(...);
> >>>>> SomeOtherFunction(v); <<== this is the last line issued before the assertion
> >>>>> failure
> >>>>>
> >>>>> [dead giveaway: the SomeFunction failed, returned NULL as documented, and you failed to
> >>>>> test for this condition before using the value]
> >>>>>
> >>>>> (c) My program, which is running under VS2008 SP1, gave an unhandled exception 0xC80000003
> >>>>> at the following line in the storage allocator:
> >>>>>
> >>>>> [dead giveaway: attempting to free something twice, storage damage due to mishandled
> >>>>> bounds on an array store or fetch, etc., especially if the values are given! The source
> >>>>> line usually has comments indicating the reason for the failure, and from this we can
> >>>>> usually make a pretty good guess]
> >>>>>
> >>>>> These are meaningful resports. All of the suggestions you give below are equivalent to
> >>>>> the word "crash" in terms of their useful content.
> >>>>>
> >>>>> Note in the definition you give, a "crash" of a computer is rather different than a
> >>>>> "crash" of a program under development, and even then the description of "crash" is for
> >>>>> people like my mother, who can't tell an unhandled kernel exception from a heap
> >>>>> corruption; all she knows is her screen turned blue and the letter she was writing is
> >>>>> lost. I expect something a bit more coherent from someone who claims to be a programmer!
> >>>>>
> >>>>> Note that all the definitions describe different conditions, which would require different
> >>>>> actions to handle. A non-responding program is quite a different problem from one which
> >>>>> has taken an unhandled exception, or one which has taken an assertion failure. Again, the
> >>>>> audiences are different; programmers are assumed to be capable of distinguishing all these
> >>>>> causes in a report and providing maximum information to allow diagnosis of the problem by
> >>>>> another programmer. So if I report that my program isn't running correctly, what,
> >>>>> exactly, do you think you can do to help me? But if I specifically say what I am
> >>>>> observing, and, as a programmer, tell you the values of the variables involved, I am
> >>>>> giving you the critical information you need to help me. This is a programmers'
> >>>>> newsgroup; I expect a programmer's description of the problem, not the description my
> >>>>> mother would give (she called me up once and said her computer said it had done something
> >>>>> illegal, and should she be concerned? But she was 85 at the time). So when a person who
> >>>>> claims to be a "programmer" says "my program crashed" I expect them to have the minimum
> >>>>> capability of reporting EXACTLY what happened in terms of the executing code!
> >>>>> joe
> >>>>>
> >>>>>
> >>>>> On Mon, 19 Apr 2010 13:15:47 -0400, Hector Santos <sant9442(a)nospam.gmail.com> wrote:
> >>>>>
> >>>>>> Ok, what do you want to say?
> >>>>>>
> >>>>>> "My program stopped working."
> >>>>>> "My program popped up GPF box"
> >>>>>> "My program faulted"
> >>>>>> "My program abend"
> >>>>>> "My program aborted"
> >>>>>> "My program refused to run."
> >>>>>> "My program quit for some reason."
> >>>>>>
> >>>>>> Crash is not suppose to describe what exactly happen. Only that
> >>>>>> ultimate outcome has occurred.
> >>>>>>
> >>>>>> Google:
> >>>>>>
> >>>>>> define: crash
> >>>>>>
> >>>>>> * stop operating; "My computer crashed last night";
> >>>>>> "The system goes down at least once a week"
> >>>>>>
> >>>>>> Webster:
> >>>>>>
> >>>>>> d) of a computer system, component, or program : to suffer a
> >>>>>> sudden major failure usually with attendant loss of data
> >>>>>>
> >>>>>> http://en.wikipedia.org/wiki/Crash
> >>>>>>
> >>>>>> # Crash (computing), a condition where a program ceases to respond
> >>>>>>
> >>>>>> I actually don't like the Wikipedia insert. It should say:
> >>>>>>
> >>>>>> # Crash (computing), a condition where a program no longer
> >>>>>> operates correctly or continues to run.
> >>>>>>
> >>>>>> It would be able to the user or developer to find out the reason why
> >>>>>> their program crashed (aborted, abend, faulted, stop running, etc,
> >>>>>> pick up).
> >>>>>>
> >>>>>> --
> >>>>>>
> >>>>>> Joseph M. Newcomer wrote:
> >>>>>>
> >>>>>>> I am SERIOUSLY trying to make people stop using the word "crash" when they do not describe
> >>>>>>> WHAT happened. Sadly, too many people confuse "assertion failure" with "crash" and NONE
> >>>>>>> of them actually spend any time in the debugger trying to figure out what went wrong.
> >>>>>>> joe
From: Ruslan Shcherbatyuk on
Even if there some quirks with GetWindowTextLength, its usage is inside of
CVSListBox internals (MFC) source code, so I can not manage it.

"David Lowndes" wrote:

> >BTW, looks like number of bytes returned by ::GetWindowText is about exactly
> >2 times bigger than ::GetWindowTextLen had returned.
>
> There are some quirks with GetWindowTextLength - see the remarks in
> the MSDN documentation.
>
> Dave
> .
>
From: Joseph M. Newcomer on
From the dump I saw, it is not returning Unicode characters.
joe
****
On Mon, 19 Apr 2010 23:55:01 -0700, Ruslan Shcherbatyuk
<RuslanShcherbatyuk(a)discussions.microsoft.com> wrote:

>BTW, looks like number of bytes returned by ::GetWindowText is about exactly
>2 times bigger than ::GetWindowTextLen had returned. My application is
>non-unicode, may be CVSListBox is somehow incompatible with non-unicode apps
>or I forget to do some 'special' initialization, like InitCommonCotrols or
>like this?
>
>Anyway I can use it in my non-unicode app by applying ctrl.SetWindowText("")
>before its OnPaint hander inside of OnInitDialog of hosting PropertyPage.
>
>"Joseph M. Newcomer" wrote:
>
>> See below...
>> On Mon, 19 Apr 2010 14:41:01 -0700, Ruslan Shcherbatyuk
>> <RuslanShcherbatyuk(a)discussions.microsoft.com> wrote:
>>
>> >New information and I still have no idea what is the problem or how to find it.
>> >I had used OnIdle and _heapchk() and assertion not happens.
>> >
>> >Below is a callstack of heap corruption moment:
>> >
>> >> ComputerZal.exe!_free_dbg_nolock(void * pUserData=0x02183d28, int nBlockUse=0x00000001) Line 1376 + 0x3b bytes C++
>> > ComputerZal.exe!_free_dbg(void * pUserData=0x02183d28, int
>> >nBlockUse=0x00000001) Line 1265 + 0xd bytes C++
>> > ComputerZal.exe!free(void * pUserData=0x02183d28) Line 49 + 0xb bytes C++
>> > ComputerZal.exe!CAfxStringMgr::Free(ATL::CStringData * pData=0x02183d28)
>> >Line 169 + 0x9 bytes C++
>> > ComputerZal.exe!ATL::CStringData::Release() Line 116 + 0x17 bytes C++
>> > ComputerZal.exe!ATL::CSimpleStringT<char,0>::~CSimpleStringT<char,0>()
>> >Line 289 C++
>> > ComputerZal.exe!ATL::CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char>
>> >> >::~CStringT<char,StrTraitMFC<char,ATL::ChTraitsCRT<char> > >() Line 1213
>> >+ 0x8 bytes C++
>> > ComputerZal.exe!CVSListBoxBase::OnPaint() Line 333 + 0xf bytes C++
>> > ComputerZal.exe!CWnd::OnWndMsg(unsigned int message=0x0000000f, unsigned
>> >int wParam=0x00000000, long lParam=0x00000000, long * pResult=0x001272c8)
>> >Line 2354 C++
>> >
>> >The problem is in destructor of CString object of CVSListBoxBase::OnPaint()
>> >method:
>> >
>> >............
>> > CString strCaption;
>> >
>> > if (m_bDefaultCaption)
>> > {
>> > GetWindowText(strCaption); // ************
>> ****
>> This cannot fail. If it is failing, you already have memory damage.
>> ****
>> > }
>> > else
>> > {
>> > strCaption = m_strCaption;
>> > }
>> >
>> > dc.DrawText(strCaption, rectText, DT_LEFT | DT_SINGLELINE | DT_VCENTER);
>> >
>> > if (pOldFont != NULL)
>> > {
>> > dc.SelectObject(pOldFont);
>> > }
>> > // HERE !!!!!!!!!!!!!!!!!!!!!!!!
>> >}
>> >
>> >Heap corruption appears inside of GetWindowText(strCaption); // ************
>> >
>> >void CWnd::GetWindowText(CString& rString) const
>> >{
>> > ASSERT(::IsWindow(m_hWnd));
>> >
>> >#ifndef _AFX_NO_OCC_SUPPORT
>> > if (m_pCtrlSite == NULL)
>> > {
>> >#endif
>> > int nLen = ::GetWindowTextLength(m_hWnd);
>> > ::GetWindowText(m_hWnd, rString.GetBufferSetLength(nLen), nLen+1);
>> >
>> >nLen is returned 0x16, and buffer is allocated of 0x16 bytes but buffer is
>> >actually filled with much more bytes in call to ::GetWindowText.
>> ****
>> And you know this how? Note that ::GetWindowText takes a maximum buffer length and will
>> not fill in more characters than the specified length.
>> ****
>> >
>> >I reproduced this behavior at the end of OnInitDialog of page where
>> >CVSListBox is placed:
>> >
>> > char buffer[128] = { 0 };
>> ****
>> First, the use of char is wrong, and the use of a buffer of a fixed size (like 128)
>> represents Worst Practice. Why did you not use CString here?
>> ****
>> > int nLen = ::GetWindowTextLength(list_custom_indmin.m_hWnd);
>> > ::GetWindowText(list_custom_indmin.m_hWnd, buffer, 128);
>> >
>> >How the buffer is look like before getting of nLen=0x16 (actually it
>> >received much more bytes):
>> >
>> >0x001263E4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x001263F6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x00126408 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x0012641A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x0012642C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x0012643E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x00126450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >
>> >and after:
>> >
>> > 00 42 65 7a 4d 46 43 56 53 4c 69 73 74 42 6f 78 00 bf .BezMFCVSListBox.?
>> >0x001263F6 4f 80 89 e3 37 7e 4f e3 37 7e 04 00 00 80 f0 69 12 00
>> >O?.?7~O?7~...??i..
>> >0x00126408 50 65 12 00 04 6a 12 00 00 00 00 00 00 00 00 00 00 00
>> >Pe...j............
>> >0x0012641A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x0012642C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x0012643E 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> >0x00126450 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>> >..................
>> ****
>> I've never seen a failure like this on GetWindowText. Essentially, it got a 0-length
>> string (the initial NUL character), and I have no idea why it would retrieve anything
>> else, but it shouldn't matter because it did not overrun the buffer
>>
>> I wonder: did someone implement a WM_GETTEXT handler for CVSListBox that is doing the
>> wrong thing? That's the first guess I would make. I'd suggest looking at the CVSListBox
>> source code to see what handlers are in its Message Map, and if there is a WM_GETTEXT, I'd
>> read its code to make sure the programmer didn't screw up big time. THat's how I'd start
>> to do the analysis.
>> joe
>> ****
>> >
>> >As you can see we received much more than 0x16 bytes.
>> ****
>> Looks like a serious error in the CVSListBox code to me
>> ****
>> >
>> >I also put _heapchk() at the end of OnInitDialog() (just before appearing of
>> >ON_PAINT of CVSListBox) and nothing is corrupted inside of heap. There are
>> >also no any threads that can corrupt something and, as I told before
>> >everything is working fine inside of x64 Win 7 where VS2010 is installed.
>> ****
>> Threads don't matter at all in this case. In fact, if there is an error of the kind I
>> described, it can happen in a single-threaded app.
>> ****
>> >
>> >I'm using remote debugging to observe bug on destination VMWare PC with
>> >WinXP x86 installed.
>> >
>> >Any recomendations? What can I try next?
>> ***
>> See above. There are a scary number of tools between you and the application, and that
>> makes me worry that anything might be broken.
>> ****
>> >
>> >Is it possible that Win7 PC has no this bug because of VS 2010 installation
>> >(may be it has other MFC/COMCTL32 dll's)? Although I am using statical MFC
>> >linking to executable.
>> ****
>> I'd do a LOT of single-stepping, and, as I said, I'd be very suspect of the CVSListBox
>> code.
>>
>> But what you are seeing is supposed to be impossible. Because it has returned a string of
>> 0 length, there should be no other characters in the string.
>> joe
>> ****
>> >
>> >I will wait for other recomendations and hope that this message has more
>> >information.
>> >"Ruslan Shcherbatyuk" wrote:
>> >
>> >> Thank you for your comments and sorry for using wrong 'crash' keyword, I will
>> >> do more deep debugging using OnIdle heap check technik and will report about
>> >> results as soon as I understand something.
>> >>
>> >> "Joseph M. Newcomer" wrote:
>> >>
>> >> > (a) My program reports an unhandled exception 0xC0000005 in the function XXXXXX at the
>> >> > following line:
>> >> > <source code here>
>> >> > I examined the variables, and the value being passed in is 0xCCCCCD8.
>> >> >
>> >> > [dead giveaway: uninitialized local pointer variable]
>> >> >
>> >> > (b) My program, which is running under VS2008 without SP1, gave an assertion failure on
>> >> > line NNNN or file XXXXXX.cpp (here is the function). I have indicated which of the
>> >> > assertions failed. When I examined the value with the debugger, it was 0 (NULL). The
>> >> > callback trace to my code is also shown, and the source line from my code is indicated
>> >> > below
>> >> > Something * v;
>> >> > ...stuff here...
>> >> > v = SomeFunction(...);
>> >> > SomeOtherFunction(v); <<== this is the last line issued before the assertion
>> >> > failure
>> >> >
>> >> > [dead giveaway: the SomeFunction failed, returned NULL as documented, and you failed to
>> >> > test for this condition before using the value]
>> >> >
>> >> > (c) My program, which is running under VS2008 SP1, gave an unhandled exception 0xC80000003
>> >> > at the following line in the storage allocator:
>> >> >
>> >> > [dead giveaway: attempting to free something twice, storage damage due to mishandled
>> >> > bounds on an array store or fetch, etc., especially if the values are given! The source
>> >> > line usually has comments indicating the reason for the failure, and from this we can
>> >> > usually make a pretty good guess]
>> >> >
>> >> > These are meaningful resports. All of the suggestions you give below are equivalent to
>> >> > the word "crash" in terms of their useful content.
>> >> >
>> >> > Note in the definition you give, a "crash" of a computer is rather different than a
>> >> > "crash" of a program under development, and even then the description of "crash" is for
>> >> > people like my mother, who can't tell an unhandled kernel exception from a heap
>> >> > corruption; all she knows is her screen turned blue and the letter she was writing is
>> >> > lost. I expect something a bit more coherent from someone who claims to be a programmer!
>> >> >
>> >> > Note that all the definitions describe different conditions, which would require different
>> >> > actions to handle. A non-responding program is quite a different problem from one which
>> >> > has taken an unhandled exception, or one which has taken an assertion failure. Again, the
>> >> > audiences are different; programmers are assumed to be capable of distinguishing all these
>> >> > causes in a report and providing maximum information to allow diagnosis of the problem by
>> >> > another programmer. So if I report that my program isn't running correctly, what,
>> >> > exactly, do you think you can do to help me? But if I specifically say what I am
>> >> > observing, and, as a programmer, tell you the values of the variables involved, I am
>> >> > giving you the critical information you need to help me. This is a programmers'
>> >> > newsgroup; I expect a programmer's description of the problem, not the description my
>> >> > mother would give (she called me up once and said her computer said it had done something
>> >> > illegal, and should she be concerned? But she was 85 at the time). So when a person who
>> >> > claims to be a "programmer" says "my program crashed" I expect them to have the minimum
>> >> > capability of reporting EXACTLY what happened in terms of the executing code!
>> >> > joe
>> >> >
>> >> >
>> >> > On Mon, 19 Apr 2010 13:15:47 -0400, Hector Santos <sant9442(a)nospam.gmail.com> wrote:
>> >> >
>> >> > >
>> >> > >Ok, what do you want to say?
>> >> > >
>> >> > > "My program stopped working."
>> >> > > "My program popped up GPF box"
>> >> > > "My program faulted"
>> >> > > "My program abend"
>> >> > > "My program aborted"
>> >> > > "My program refused to run."
>> >> > > "My program quit for some reason."
>> >> > >
>> >> > >Crash is not suppose to describe what exactly happen. Only that
>> >> > >ultimate outcome has occurred.
>> >> > >
>> >> > >Google:
>> >> > >
>> >> > > define: crash
>> >> > >
>> >> > > * stop operating; "My computer crashed last night";
>> >> > > "The system goes down at least once a week"
>> >> > >
>> >> > >Webster:
>> >> > >
>> >> > > d) of a computer system, component, or program : to suffer a
>> >> > > sudden major failure usually with attendant loss of data
>> >> > >
>> >> > >http://en.wikipedia.org/wiki/Crash
>> >> > >
>> >> > > # Crash (computing), a condition where a program ceases to respond
>> >> > >
>> >> > >I actually don't like the Wikipedia insert. It should say:
>> >> > >
>> >> > > # Crash (computing), a condition where a program no longer
>> >> > > operates correctly or continues to run.
>> >> > >
>> >> > >It would be able to the user or developer to find out the reason why
>> >> > >their program crashed (aborted, abend, faulted, stop running, etc,
>> >> > >pick up).
>> >> > >
>> >> > >--
>> >> > >
>> >> > >Joseph M. Newcomer wrote:
>> >> > >
>> >> > >> I am SERIOUSLY trying to make people stop using the word "crash" when they do not describe
>> >> > >> WHAT happened. Sadly, too many people confuse "assertion failure" with "crash" and NONE
>> >> > >> of them actually spend any time in the debugger trying to figure out what went wrong.
>> >> > >> joe
>> >> > >>
>> >> > >> On Mon, 19 Apr 2010 11:19:01 -0400, Hector Santos <sant9442(a)nospam.gmail.com> wrote:
>> >> > >>
>> >> > >>> Joseph M. Newcomer wrote:
>> >> > >>>
>> >> > >>>> This doesn't work because there is no way to "walk around" an instance of heap damage.
>> >> > >>>>
>> >> > >>>> The analogy is intended to be simple, to cover the simple case. You are tryiing to
>> >> > >>>> stretch it by bringing in mechanisms that simply do not exist. There are really only two
>> >> > >>>> options: fall into the hole, or know that there is an open manhole somewhere on the street
>> >> > >>>> into which you may or may not fall. That's all the mechanisms that exist.
>> >> > >>>>
>> >> > >>>> The point of the analogy is to indicate the temporal separation between the event and its
>> >> > >>>> detection; it is a common confusion to believe that the even that detected the problem is
>> >> > >>>> the event that caused the problem.
>> >> > >>>
>> >> > >>> I don't disagree.
>> >> > >>>
>> >> > >>> My point is that people must have the understanding of its existence
>> >> > >>> and how it plays a role before they can make any conclusion or
>> >> > >>> intelligent guess work at problem detection and resolution.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm