From: Ruslan Shcherbatyuk Ruslan on
I have strange CVSListBox heap corruption crash under the following
environment:
VS-2010, XP-SP3-32bit, Non-unicode, Statically linked MFC App, Debug
CVSListBox is placed on the CPropertyPage. The same with Vista 32bit.
Heap crash appears when I switch to the tab where CVSListBox located.

At the same time this application is not crashed under Windows7 x64 where
Visual Studio 2010 is installed and application was compiled.

Deep debugging shows me that the problem is in CVSListBoxBase::OnPaint
method, CString release. Problem appears when CVSListBox has no caption and
uses default one (""). I can fix this problem by using SetWindowText("") to
CVSListBox control inside of OnInitDialog of the CPropertyPage, but this is a
workaround. I aslo used Spy++ on HWND window of CVSListBoxBase::GetWindowText
and saw that GetWindowTextLength is 10 but actual GetWindowText returns "\0"
if it is important.

Can somebody comment or describe me what is exactly wrong? Unfortunately the
project is very big and I can't post it here.
From: David Ching on
"Ruslan Shcherbatyuk" <Ruslan Shcherbatyuk(a)discussions.microsoft.com> wrote
in message news:C7CDF49F-B79E-4205-A166-D344905AD1F9(a)microsoft.com...
> Deep debugging shows me that the problem is in CVSListBoxBase::OnPaint
> method, CString release. Problem appears when CVSListBox has no caption
> and
> uses default one (""). I can fix this problem by using SetWindowText("")
> to
> CVSListBox control inside of OnInitDialog of the CPropertyPage, but this
> is a
> workaround. I aslo used Spy++ on HWND window of
> CVSListBoxBase::GetWindowText
> and saw that GetWindowTextLength is 10 but actual GetWindowText returns
> "\0"
> if it is important.
>

Is it a logic error in CVSListBox that it mishandles the CString when there
is none, or something else? How does CVSListBox or its ancestors like
CVSListBoxBase handle WM_GETTEXT (which is called when GetWindowText is
called)?


> Can somebody comment or describe me what is exactly wrong? Unfortunately
> the
> project is very big and I can't post it here.

Try to repro it by creating a simple dialog app and putting a CVSListBox
inside it.

-- David

From: Ruslan Shcherbatyuk on
> Is it a logic error in CVSListBox that it mishandles the CString when there
> is none, or something else?

No idea

> How does CVSListBox or its ancestors like
> CVSListBoxBase handle WM_GETTEXT (which is called when GetWindowText is
> called)?

Nothing special:
LRESULT CVSListBoxBase::OnSetText(WPARAM, LPARAM lParam)
{
LPCTSTR lpcszTitle = reinterpret_cast<LPCTSTR>(lParam);
if (lpcszTitle != NULL)
{
m_strCaption = lpcszTitle;
m_bDefaultCaption = FALSE;
}
else
{
m_bDefaultCaption = TRUE;
m_strCaption.Empty();
}

RedrawWindow();
return Default();
}

> > Can somebody comment or describe me what is exactly wrong? Unfortunately
> > the project is very big and I can't post it here.
> Try to repro it by creating a simple dialog app and putting a CVSListBox
> inside it.

I've just made simple app with property sheet, few pages with CVSListBox and
everything works fine. So I cant reproduce this behavior, only inside of my
'big' application. May be heap corruption is done by some my other code...
Big application has stable false behavior. Interesting, why I dont have it on
Win7 x64 where VS2010 and have it on x86 Win XP, Vista, 7.
From: Joseph M. Newcomer on
See below...
On Sun, 18 Apr 2010 01:25:04 -0700, Ruslan Shcherbatyuk <Ruslan
Shcherbatyuk(a)discussions.microsoft.com> wrote:

>I have strange CVSListBox heap corruption crash under the following
>environment:
>VS-2010, XP-SP3-32bit, Non-unicode, Statically linked MFC App, Debug
>CVSListBox is placed on the CPropertyPage. The same with Vista 32bit.
>Heap crash appears when I switch to the tab where CVSListBox located.
>
>At the same time this application is not crashed under Windows7 x64 where
>Visual Studio 2010 is installed and application was compiled.
****
You have given a lot of valuable information, but unfortunately, not *complete*
information.

I have no idea what a "heap crash" is. In fact, you should NEVER use the word "crash"
unless you give a VERY detailed description of what has gone wrong.

For example: an assertion failure is NOT a "crash" in the strict sense, although it is a
common error and tends to indicate a condition that can lead to a fatala application
error. Assertion failures always have file names and line numbers, which are critical to
the understanding of the error.

A debug breakpoint taken in the allocator (int 3) always appears on a certain line of a
specific function, and knowing WHICH int 3 you hit can tell us a lot.

If there is a fatal application error. it is almost always an access fault, and if it
occurs, it occurs on a specific instruction. But we need to know what really happened.

It is a common misconception that if there is an error detected in the storage allocator,
it must have been "caused" by the call that results in the detection. This is incorrect.
The damage could have been done by a variety of programming error,s *billions* of
instructions in the past, and what you are seeing is the first instance of when it is
*detected*, which does not correlate to cause. The analogy I use is that you were walking
down the street and fell into an open manhole. The real offense was when the cover was
removed, not when you fell in. So it is not possible to attribute it directly to
CVSListBox. And the effects of doing an allocation (such as for a string) can change the
heap patterns so the error moves and is not detected at the same time. This means the
error has not actually gone away, but the conditions that caused that specific detection
are different. To go to the manhole analogy, suppose that when the person who was going
to remove the cover looked around, he saw other people on the street. These people might
notice what had happened. So he goes and removes a cover on some other street. Note that
you cannot say "By putting a person on the street, we solved the problem". You didn't.
But without the detailed knowledge of what has happened, it is hard to say what is going
on. And while you did an excellent job at some of the details of the report, you really
need to do a *complete* report.
joe
****
>
>Deep debugging shows me that the problem is in CVSListBoxBase::OnPaint
>method, CString release. Problem appears when CVSListBox has no caption and
>uses default one (""). I can fix this problem by using SetWindowText("") to
>CVSListBox control inside of OnInitDialog of the CPropertyPage, but this is a
>workaround. I aslo used Spy++ on HWND window of CVSListBoxBase::GetWindowText
>and saw that GetWindowTextLength is 10 but actual GetWindowText returns "\0"
>if it is important.
>
>Can somebody comment or describe me what is exactly wrong? Unfortunately the
>project is very big and I can't post it here.
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm
From: Hector Santos on
I don't know if I agree with your manhole analogy. :) Its a matter of
anticipation, expectation and knowledge of their existence and current
state.

If you never were aware of manholes, then you have no path planning
(assert checks), not run time logic to check for them:

void WalkStreet()
{
WaitStraight();
}

If you expect manholes, and they might be open, then you might have:

void WalkStreet()
{
if (ManHole.Opened()) {
WalkAround();
} else {
WalkStraight();
}
}

If the manhole MUST be closed at all times (a design concept), then an
assertion is appropriate:

void WalkStreet()
{
assert(ManHole.Opened());
WalkStraight();
}

But if its possible, but not expected by the time you walk the street
or walking around the manhole is a performance issue (no longer a
straight line), then you could have:

void WalkStreet()
{
if (ManHole.Opened()) {
ReportToCity("ManHole #%d left open", ManHole.Number);
If (ManHole.Cover.Location == NEARBY) {
ManHole.Close();
} else {
WalkAround();
return;
}
}
WalkStraight();
}

I guess your point is that he should be checking for ManHoles. :)

--
HLS

Joseph M. Newcomer wrote:

> See below...
> On Sun, 18 Apr 2010 01:25:04 -0700, Ruslan Shcherbatyuk <Ruslan
> Shcherbatyuk(a)discussions.microsoft.com> wrote:
>
>> I have strange CVSListBox heap corruption crash under the following
>> environment:
>> VS-2010, XP-SP3-32bit, Non-unicode, Statically linked MFC App, Debug
>> CVSListBox is placed on the CPropertyPage. The same with Vista 32bit.
>> Heap crash appears when I switch to the tab where CVSListBox located.
>>
>> At the same time this application is not crashed under Windows7 x64 where
>> Visual Studio 2010 is installed and application was compiled.
> ****
> You have given a lot of valuable information, but unfortunately, not *complete*
> information.
>
> I have no idea what a "heap crash" is. In fact, you should NEVER use the word "crash"
> unless you give a VERY detailed description of what has gone wrong.
>
> For example: an assertion failure is NOT a "crash" in the strict sense, although it is a
> common error and tends to indicate a condition that can lead to a fatala application
> error. Assertion failures always have file names and line numbers, which are critical to
> the understanding of the error.
>
> A debug breakpoint taken in the allocator (int 3) always appears on a certain line of a
> specific function, and knowing WHICH int 3 you hit can tell us a lot.
>
> If there is a fatal application error. it is almost always an access fault, and if it
> occurs, it occurs on a specific instruction. But we need to know what really happened.
>
> It is a common misconception that if there is an error detected in the storage allocator,
> it must have been "caused" by the call that results in the detection. This is incorrect.
> The damage could have been done by a variety of programming error,s *billions* of
> instructions in the past, and what you are seeing is the first instance of when it is
> *detected*, which does not correlate to cause. The analogy I use is that you were walking
> down the street and fell into an open manhole. The real offense was when the cover was
> removed, not when you fell in. So it is not possible to attribute it directly to
> CVSListBox. And the effects of doing an allocation (such as for a string) can change the
> heap patterns so the error moves and is not detected at the same time. This means the
> error has not actually gone away, but the conditions that caused that specific detection
> are different. To go to the manhole analogy, suppose that when the person who was going
> to remove the cover looked around, he saw other people on the street. These people might
> notice what had happened. So he goes and removes a cover on some other street. Note that
> you cannot say "By putting a person on the street, we solved the problem". You didn't.
> But without the detailed knowledge of what has happened, it is hard to say what is going
> on. And while you did an excellent job at some of the details of the report, you really
> need to do a *complete* report.
> joe
> ****
>> Deep debugging shows me that the problem is in CVSListBoxBase::OnPaint
>> method, CString release. Problem appears when CVSListBox has no caption and
>> uses default one (""). I can fix this problem by using SetWindowText("") to
>> CVSListBox control inside of OnInitDialog of the CPropertyPage, but this is a
>> workaround. I aslo used Spy++ on HWND window of CVSListBoxBase::GetWindowText
>> and saw that GetWindowTextLength is 10 but actual GetWindowText returns "\0"
>> if it is important.
>>
>> Can somebody comment or describe me what is exactly wrong? Unfortunately the
>> project is very big and I can't post it here.
> Joseph M. Newcomer [MVP]
> email: newcomer(a)flounder.com
> Web: http://www.flounder.com
> MVP Tips: http://www.flounder.com/mvp_tips.htm