From: Michael on 28 Jul 2008 05:40 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 28 Jul 2008 10:21 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 28 Jul 2008 11:09 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
|
Pages: 1 Prev: Overriding the CDateTimeCtrl class. Next: Change background of CEditView |