From: Michael on
Basic question is... is CString thread safe in all cases?

I've read somewhere that CString is thread safe class wise but not
instance wise. The thing is we've made sure that our CString objects
are not being accessed by more than one thread by using
synchronization objects. But we are still getting crashes with this
particular stack dump from the offending thread.

msvcr80!_vsprintf_s_l+0x7c
msvcr80!vsprintf_s+0x17
mfc80!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> >
>::FormatV+0x40
mfc80!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> >
>::Format+0x12

Its seems to be always at this point. I studied the latest dump using
WinDbg version 6.9.0003.113 and it indicated a possible heap
corruption. I tried to pursue this line of inquiry which lead me to
question the thread safety of CString. I also saw something in VC
documentation saying that a CString can be passed a heap allocator and
each thread can have its own heap manager.

Is this the correct solution? Should I create a separate heap manager/
allocator for each thread and assign them to CString so that when
CString needs to resize it won't cause any heap corruption?

Thanks a lot in advance!
From: Alexander Grigoriev on
Show us how you call CString::Format

Note that you should not be passing the same string as an argument to Format
function.


"Michael" <lightningmtm(a)gmail.com> wrote in message
news:2aa5f359-a68c-4454-964b-579d3c24651a(a)h17g2000prg.googlegroups.com...
> Basic question is... is CString thread safe in all cases?
>
> I've read somewhere that CString is thread safe class wise but not
> instance wise. The thing is we've made sure that our CString objects
> are not being accessed by more than one thread by using
> synchronization objects. But we are still getting crashes with this
> particular stack dump from the offending thread.
>
> msvcr80!_vsprintf_s_l+0x7c
> msvcr80!vsprintf_s+0x17
> mfc80!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> >
>>::FormatV+0x40
> mfc80!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> >
>>::Format+0x12
>
> Its seems to be always at this point. I studied the latest dump using
> WinDbg version 6.9.0003.113 and it indicated a possible heap
> corruption. I tried to pursue this line of inquiry which lead me to
> question the thread safety of CString. I also saw something in VC
> documentation saying that a CString can be passed a heap allocator and
> each thread can have its own heap manager.
>
> Is this the correct solution? Should I create a separate heap manager/
> allocator for each thread and assign them to CString so that when
> CString needs to resize it won't cause any heap corruption?
>
> Thanks a lot in advance!


From: Joseph M. Newcomer on
See below...
On Mon, 28 Jul 2008 02:40:22 -0700 (PDT), Michael <lightningmtm(a)gmail.com> wrote:

>Basic question is... is CString thread safe in all cases?
>
>I've read somewhere that CString is thread safe class wise but not
>instance wise.
****
I'm not sure what is meant by the phrase "thread safe class wise" but it is *definitely*
not thread-safe instance-wise.
****
>The thing is we've made sure that our CString objects
>are not being accessed by more than one thread by using
>synchronization objects.
****
I find the concept scary. You should not create situations in which you need to do this
kind of synchronization. But if you do it right, it should work correctly
****
>But we are still getting crashes with this
>particular stack dump from the offending thread.
>
>msvcr80!_vsprintf_s_l+0x7c
>msvcr80!vsprintf_s+0x17
>mfc80!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> >
>>::FormatV+0x40
>mfc80!ATL::CStringT<char,StrTraitMFC_DLL<char,ATL::ChTraitsCRT<char> >
>>::Format+0x12
****
And what is it doing at that point? What's the code?
****
>
>Its seems to be always at this point. I studied the latest dump using
>WinDbg version 6.9.0003.113 and it indicated a possible heap
>corruption.
****
If there is heap corruption, note that you may be seeing the error at the point of
*detection*, not at the point where the damage was done, and therefore the damage could be
done anywhere, at any time, possibly billions of instructions before the error detection.
****
>I tried to pursue this line of inquiry which lead me to
>question the thread safety of CString. I also saw something in VC
>documentation saying that a CString can be passed a heap allocator and
>each thread can have its own heap manager.
*****
Each thread *could* have its own heap manager, but getting CString to use it can be a bit
challenging; by default, CStrings are on the "default heap" and unless you have gone
through a lot of effort to get around this, that's what is happening.
****
>
>Is this the correct solution? Should I create a separate heap manager/
>allocator for each thread and assign them to CString so that when
>CString needs to resize it won't cause any heap corruption?
****
No. I suspect the damage could be elsewhere, and you are confusing detection with cause.
In fact, creating separate per-thread heaps is extremely dangerous, because it means you
cannot manipulate the CString once it has been created, *except* in the creating thread
context, which also means you cannot delete it, or otherwise touch it *except in read-only
mode*, in any but the creating thread. That opens you up to more disasters than it is
worth contemplating. It would be a very, very hazardous thing to do.

One trick I use is to create an OnIdle handler in the CWinApp class and do
ASSERT(_heapchk() == HEAP_OK);
[check the docs to see if I remembered all the spellings correctly--it might be HEAPOK,
etc.] and that forces the heap to be checked for consistency each time I end up in the
idle loop, which can detect memory damage early. In addition, make sure that in your
CString::Format (which is what is calling the vsprintf) you have a correct correspondence
between format types and arguments; for example, a %s using an integer argument might
trigger an error that looks like heap damage, and so on
joe
****
>
>Thanks a lot in advance!
Joseph M. Newcomer [MVP]
email: newcomer(a)flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm