From: Joseph M. Newcomer on
See below...
On Tue, 20 Apr 2010 03:55:23 -0400, Hector Santos <sant9442(a)nospam.gmail.com> 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);
****
GetWindowText takes a CString& parameter, so the call would be
...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.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm