| View previous topic :: View next topic |
| Author |
Message |
Asgard Site Admin
Joined: 26 Nov 2002 Posts: 228 Location: Austria
|
Posted: Sat May 31, 2003 11:34 am Post subject: Fix for MSVC 7.x Release Build Issues with wxWindows |
|
|
MSVC 7.x has a bug when building release builds with regard to wxWindows RTTI that causes all release build wxWindows applications to crash, typically right during startup.
This is a (temporary) fix for the issue for wxWindows 2.4.0.
Open %WXWIN%/src/common/object.cpp and change this code
| Code: | wxClassInfo wxObject::sm_classwxObject( wxT("wxObject"), 0, 0,
(int) sizeof(wxObject),
(wxObjectConstructorFn) 0 );
|
to this
| Code: |
#if defined(__VISUALC__) && __VISUALC__ >= 1300
#pragma optimize("", off)
#endif
wxClassInfo wxObject::sm_classwxObject( wxT("wxObject"), 0, 0,
(int) sizeof(wxObject),
(wxObjectConstructorFn) 0 );
#if defined(__VISUALC__) && __VISUALC__ >= 1300
#pragma optimize("", on)
#endif
|
Thanks.
Last edited by Asgard on Wed Nov 05, 2003 8:15 pm; edited 3 times in total |
|
| Back to top |
|
 |
Asgard Site Admin
Joined: 26 Nov 2002 Posts: 228 Location: Austria
|
Posted: Sun Jun 01, 2003 9:55 am Post subject: |
|
|
For those interested, here are the mails about the MSVC 7 release build issues I posted to the wx-users mailing list. They give a bit of background information on what's going on:
----------------------------------------
The problem is that release builds with MSVC 7.x crash because of the initialization routines of wxModule-derived classes do not get called. In fact, the problem is a bit different. The problem is that certain classes (among them wxModule, wxEvtHandler, or wxEvent) do not get added to the static list wxClassInfo::sm_first.
This also means that in wxClassInfo::InitializeClasses the m_baseInfo1 and m_baseInfo2 members of each wxClassInfo instance do not get initialized for classes directly derived from the aforementioned classes. For example, after InitializeClasses has finished, wxThreadModule::sm_classwxThreadModule.m_baseInfo1 is still 0, although it should point to wxModule::sm_classwxModule. The reason, again, is that wxModule is not in the wxClassInfo list when InitializeClasses is called and will therefore not get added to the hash table which is then used to fill the m_baseInfo1 member. This in turn causes wxModule::RegisterModules to fail later on.
So in fact, it's not only the wxModule subsystem that is influenced by the problem but wxWindows RTTI as a whole. Like I wrote above, wxEvent is not in the wxClassInfo list either. Therefore the following code:
| Code: |
wxMouseEvent event;
wxMessageBox(event.GetClassInfo()->IsKindOf(CLASSINFO(wxEvent)) ? wxT("true") : wxT("false"));
|
will always pop up a message box with the text "false" in MSVC 7 release builds, simply because the m_baseInfo1 member of wxMouseEvent::sm_classwxMouseEvent is 0 although it should point to wxEvent::sm_classwxEvent. In debug builds a "true" message box pops up, as expected.
Now the question remains, why is this happening...and that's what I have yet to find out. I couldn't find a pattern that would explain why certain classes do not get added to the wxClassInfo::sm_first list. Maybe somebody has some clues as to what's going on from what I wrote above, or maybe a hint on where to look next, since I'm not all too familiar with wxWindows internals.
In the meantime, I'll continue to do some more debugging.
----------------------------------------
I finally pinned down the MSVC 7 release build problem. The problematic code for the MSVC 7 compiler from object.h/object.cpp is this:
| Code: |
// wxClassInfo constructor from include/wx/object.h
wxClassInfo::wxClassInfo( const wxChar *className,
const wxChar *baseName1,
const wxChar *baseName2,
int size,
wxObjectConstructorFn ctor )
: m_className(className)
, m_baseClassName1(baseName1)
, m_baseClassName2(baseName2)
, m_objectSize(size)
, m_objectConstructor(ctor)
, m_baseInfo1(0)
, m_baseInfo2(0)
, m_next(sm_first)
{ sm_first = this; }
// static initialization of the wxObject class object
// from /src/common/object.cpp
wxClassInfo wxObject::sm_classwxObject( wxT("wxObject"), 0, 0,
(int) sizeof(wxObject),
(wxObjectConstructorFn) 0 );
|
When MSVC compiles the static initialization of sm_classwxObject it inlines the wxClassInfo constructor. However, it doesn't completely inline it. Instead, all that gets compiled is the sm_first = this;
For some reason that is beyond me at the moment, the other member variables of sm_classwxObject get initialized as well...erm...somehwere. For example, m_objectSize is initialized to 8, even though no code is compiled for it (or at least, I couldn't locate it). Maybe the compiler uses a pre-initialized copy of sm_classwxObject and stores it in the data segment of the wxWindows DLL.
In either case, the initializer m_next(sm_first) when constructing sm_classwxObject doesn't get properly compiled (or inlined, if you want). Instead, it always contains the value NULL. This causes the wxClassInfo::sm_first list to stop at the point where wxObject was inserted into the list since sm_classwxObject.m_next remains NULL, which indicates the end of the list (although it isn't). This in turn is the reason why wxClassInfo::InitializeClasses cannot properly initialize the hash table for the wxClassInfo instances.
At first I thought it would be easy to fix and I just changed the body of the wxClassInfo constructor to this (removing the m_next(sm_first) initializer):
{ m_next = sm_first; sm_first = this; }
But that didn't do any good. Again the compiler only made code for the sm_first = this; statement and simply ignored the additional m_next = sm_first;
After a bit of experimenting I found out that I could get MSVC to properly compile and inline the additional m_next = sm_first; for sm_classwxObject if I called another function which cannot be inlined from within that constructor.
So for now, until someone comes up with something better, I propose to make the following change to the wxClassInfo constructor to get MSVC 7.x release builds to work again:
| Code: |
wxClassInfo::wxClassInfo( const wxChar *className,
const wxChar *baseName1,
const wxChar *baseName2,
int size,
wxObjectConstructorFn ctor )
: m_className(className)
, m_baseClassName1(baseName1)
, m_baseClassName2(baseName2)
, m_objectSize(size)
, m_objectConstructor(ctor)
, m_baseInfo1(0)
, m_baseInfo2(0)
, m_next(sm_first)
{
#if !defined __WXDEBUG__ && defined _MSC_VER && _MSC_VER >= 1300
_tprintf(wxEmptyString);
m_next = sm_first;
#endif
sm_first = this;
}
|
I'm using printf here because stdio.h is already included. Any other function that can not be inlined should do the trick (I also tried OutputDebugString, for example, but that would require the inclusion of windows.h in object.h).
For other people using MSVC 7.x, please try the above fix in your local wxWindows copy and report back whether it also works for you. I can currently only test with MSVC 7.0 because the MSVC 7.1 CDs I have on order have not yet arrived.
You can find the wxClassInfo constructor that needs to be changed in %WXWIN%/include/wx/object.h
Of course, this fix doesn't make the problem in the MSVC compiler go away and it might come back to haunt us in other places. I tried to reproduce the issue with a simple example program but failed unfortunately.
----------------------------------------
I have found a somewhat better solution than what I proposed in my last mail regarding the MSVC 7.x release build crashes.
To get rid of the issues simply change this in src/common/object.cpp
| Code: |
wxClassInfo wxObject::sm_classwxObject( wxT("wxObject"), 0, 0,
(int) sizeof(wxObject),
(wxObjectConstructorFn) 0 );
|
to this
| Code: |
#if defined _MSC_VER && _MSC_VER >= 1300
#pragma optimize("", off)
#endif
wxClassInfo wxObject::sm_classwxObject( wxT("wxObject"), 0, 0,
(int) sizeof(wxObject),
(wxObjectConstructorFn) 0 );
#if defined _MSC_VER && _MSC_VER >= 1300
#pragma optimize("", on)
#endif
|
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|