CString Crash in _CrtIsValidHeapPointer() 
Author Message
 CString Crash in _CrtIsValidHeapPointer()

Hello,

I did build in Visual Studio .NET (7.0.9492, Trial) an application
(EXE) with VC 5.0 projects. When I run the application, it does crash
in both debug and release build. In debug build it does crash in
_CrtIsValidHeapPointer. Reason: The reference counter of (new) created
empty CStrings is exactly 1 and CAfxStringMgr::Reallocate() calls
realloc() on the address, which CAfxStringMgr::GetNilString() returns.
You can reproduce this by setting the member nrefs to 1 at the address
wich CAfxStringMgr::GetNilString() returns, here 0x7c2eff14, and call
CString::GetBuffer(int) or CString::GetBufferSetLength() on an empty
created CString. Watch variable for setting (in my environment):
((const ATL::CStringData* const)0x7c2eff14)->nRefs. This is the adress
of every created empty CString object, eg. "CString s;"

If this member can be 1, and why it should'nt (Higher values: No
problem): Why CString calls realloc() on an adress, where it is not
"allowed" (empty string value should be always "empty").

All projects use the MFC as a shared DLL and there is no mix with
debug and release versions. Even if I put all files of all projects in
only one project, there is the same behaviour.

Thank You for answering.

Elmar



Fri, 15 Apr 2005 18:19:04 GMT  
 CString Crash in _CrtIsValidHeapPointer()

Quote:
>...
>Even if I put all files of all projects in
>only one project, there is the same behaviour.

Elmar,

I think you need to show a few lines of code that gives a simple
example to illustrates the problem.

Dave
--
MVP VC++ FAQ: http://www.mvps.org/vcfaq



Fri, 15 Apr 2005 22:30:14 GMT  
 CString Crash in _CrtIsValidHeapPointer()

Quote:

> I think you need to show a few lines of code that gives a simple
> example to illustrates the problem.

Hi,

I don't have actually the code here, so the following is posted what I
have in mind. One place is the MFC CRecordset in BuildSQL() the
instruction m_strSQL = lpszSQL. Another ist DDX_Text(), where a string
is set to the CString reference Parameter in the function, the CString
is empty and nrefs is 1. The CRecordset is derived (e.g. crash in
Open() call to the CRecordset derived class), but the crash is in
CRecordset::BuildSQL().

This is only happens, if the reference counter to an empty CString is
1, then the method IsShared() returns false and the method Fork()
isn't called (forcing Fork() via De{*filter*} helps, if the reference
counter is set after Fork() to 2, but this is only possible while
debugging and the application crashes while WM_CLOSE).

You can reproduce this:

void TestApp::test() {
        CString s;
        s.GetBuffer(25); // Breakpoint here and set nrefs

Quote:
}

If You set before the call s.GetBuffer() ((const ATL::CStringData*
const)0x7c2eff14)->nRefs to 1, then CString crashes. 0x7c2eff14 is the
address, wich CAfxStringMgr::GetNilString() returns.


Fri, 15 Apr 2005 23:28:34 GMT  
 CString Crash in _CrtIsValidHeapPointer()

Quote:
>I don't have actually the code here, so the following is posted what I
>have in mind.

Elmar,

It'd be best if you can come up with as simple an example as possible
for someone to be able to reproduce this.

Quote:
>You can reproduce this:

>void TestApp::test() {
>    CString s;
>    s.GetBuffer(25); // Breakpoint here and set nrefs
>}

I'm not sure what you're proposing with this.

Do you have an example that doesn't require doing manual damage with
the de{*filter*}?

Dave
--
MVP VC++ FAQ: http://www.*-*-*.com/



Sat, 16 Apr 2005 01:22:40 GMT  
 CString Crash in _CrtIsValidHeapPointer()

Quote:

> I'm not sure what you're proposing with this.

> Do you have an example that doesn't require doing manual damage with
> the de{*filter*}?

Hi,

The problem is: I can't give an code example which reproduces that -
if I could do that, I would be able to find critical code sections and
prevent the exception.

The reference counter of a new created empty string (surely) does
increase by creating a new empty string and it decreases by destroying
the string or using operator=(), which results that the data pointer
points to the other string data.

Fact is, that GetBuffer(int) and GetBufferSetLength() causes an
exception, if called on a empty string when nrefs == 1 and the data
pointer points to the address CAfxStringMgr::GetNilString(). So, nrefs
should never be 1 or if calling that methods, that should be checked
(e.g. if (nrefs == 1 && data == CAfxStringMgr::GetNilString())
doSpecialStuff();). Unfortunately the crash happens in MFC Code
(CRecordset, DDX_Text()). Correct and recompile the MFC is not a good
idea and catching the exception is not useful because CRecordset does
not open or DDX_Text() doesn't get text.

To stop the De{*filter*} when nrefs == 1 didn't help (it did not show an
obviously coding error - that could be very earlier) an stopping every
time, when nrefs changes is not practically because this must be a few
thousend times till the crash occurs (Only in short code segments I
gave up after 50 changes - the large use count shows that reference
counting does make sense to improve speed).

The code did work for years before switching to Visual Studio .NET and
MFC 7. That does not mean, that there is no error in the code, but it
is difficult to search, it will be better, when I know under which
circumstances nrefs of an empty string could be 1 (Multithreading?).
It also could be an error in the MFC code but I did never read that
anotherone did detect the same error.

Elmar



Sun, 17 Apr 2005 23:07:33 GMT  
 CString Crash in _CrtIsValidHeapPointer()

Quote:
>The problem is: I can't give an code example which reproduces that..

Are you sure you're not chasing a bug in your own code that's giving
rise to what you're seeing?

If the problem is in the MFC source, it should be possible to come up
with a repro to illustrate it.

Quote:
>pointer points to the address CAfxStringMgr::GetNilString(). So, nrefs
>should never be 1 or if calling that methods, that should be checked
>(e.g. if (nrefs == 1 && data == CAfxStringMgr::GetNilString())
>doSpecialStuff();).

Can you temporarily add your own code function to override the MFC
source code and so catch this situation?

Have you tried running your code under a product like Bounds Checker,
or Purify to see if they can identify any problems?

You mention using GetBuffer, do you have any mismatched calls to
ReleaseBuffer?

I don't know what else to suggest, other than to use deduction based
on your understanding of your code to try and come up with some
circumstance that might give rise to complications.

Dave
--
MVP VC++ FAQ: http://www.mvps.org/vcfaq



Mon, 18 Apr 2005 01:27:17 GMT  
 CString Crash in _CrtIsValidHeapPointer()
Hello Dave,

thank you for the suggestions.

Elmar



Mon, 18 Apr 2005 16:34:12 GMT  
 
 [ 7 post ] 

 Relevant Pages 

1. CrtIsValidHeapPointer crash

2. I gots those CString::Release _CrtIsValidHeapPointer blues again

3. CString assignment crashes my system

4. Loading CString Crashes

5. CString crashes (newbie)

6. CString and the big crash!

7. Program crashes when CString deallocates values.

8. The CString implementation bug (multithreading crash)!

9. when use CString in CFile.Open - get crash

10. _CrtIsValidHeapPointer failure while registering a COM dll built with /clr option

11. CrtIsValidHeapPointer

12. _CrtIsValidHeapPointer (pUserData)???

 

 
Powered by phpBB® Forum Software