I have been getting this really weird string crash.
Background:
I have a C++ function that is called by another C++ function, that is called from angelscript
inline void WStringToString(const std::wstring &ws, std::string &s)
{
s = std::string(ws.begin(), ws.end());
}
void QuestData::SetQuestClass(std::wstring moduleName, std::wstring classname)
{
std::string modulenameAscii = WStringToString(moduleName);
std::string classnameAscii = WStringToString(classname);
}
Registered via:
r = scriptEngine->RegisterObjectMethod("QuestData", "void SetQuestClass(string,string)", asMETHOD(QuestData,SetQuestClass), asCALL_THISCALL); assert( r >= 0 );
Called from angelscript via:
QuestData quest;
quest.SetQuestClass("Tutorial","TutorialData");
Using compiler MSVC2010, X86 target, debug mode
WStringToString crashes with: "Unhandled exception at 0x011dc989 in server.exe: 0xC000000F, Access violation reading 0xdddddde1"
Happens in xutility, on line: 146: _Mynextiter = _Parent_proxy->_Myfirstiter;
> Server.exe!std::_Iterator_base12::_Adopt(const std::_Container_base12 * _Parent) Line 146 + 0x6 bytes C++
Server.exe!std::_Iterator_base12::operator=(const std::_Iterator_base12 & _Right) Line 124 C++
Server.exe!std::_Iterator_base12::_Iterator_base12(const std::_Iterator_base12 & _Right) Line 118 C++
Server.exe!std::_Iterator012<std::random_access_iterator_tag,wchar_t,int,wchar_t const *,wchar_t const &,std::_Iterator_base12>::_Iterator012<std::random_access_iterator_tag,wchar_t,int,wchar_t const *,wchar_t const &,std::_Iterator_base12>(const std::_Iterator012<std::random_access_iterator_tag,wchar_t,int,wchar_t const *,wchar_t const &,std::_Iterator_base12> & __that) + 0x2f bytes C++
Server.exe!std::_String_const_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >::_String_const_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >(const std::_String_const_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & __that) + 0x2f bytes C++
Server.exe!std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string<char,std::char_traits<char>,std::allocator<char> ><std::_String_const_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > >(std::_String_const_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > _First, std::_String_const_iterator<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > _Last) Line 623 + 0x37 bytes C++
Server.exe!WStringToString(const std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > & ws) Line 108 + 0x56 bytes C++
Server.exe!QuestData::SetQuestClass(std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > moduleName, std::basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> > classname) Line 107 + 0xd bytes C++
Server.exe!CallThisCallFunction(const void * obj, const unsigned long * args, int paramSize, void (void)* func) Line 1053 C++
Server.exe!CallSystemFunctionNative(asCContext * context, asCScriptFunction * descr, void * obj, unsigned long * args, void * retPointer, unsigned __int64 & __formal) Line 170 + 0x1b bytes C++
Server.exe!CallSystemFunction(int id, asCContext * context, void * objectPointer) Line 486 + 0x37 bytes C++
Server.exe!asCContext::ExecuteNext() Line 2309 + 0x12 bytes C++
Server.exe!asCContext::Execute() Line 1144 + 0x8 bytes C++
Server.exe!ScriptManager::ExecuteScript() Line 234 + 0x17 bytes C++
<Snip, more of my own code>
Now the weirdest thing is, changing the C++ code to
void QuestData::SetQuestClass(std::wstring moduleName, std::wstring classname)
{
std::wstring tmp = moduleName;
std::string modulenameAscii = WStringToString(tmp);
tmp = classname;
std::string classnameAscii = WStringToString(tmp);
}
And it works fine. But I don't want to use that solution as it seems like this is an indication of a underlying bug.
I disabled MSVC's 'internal hiding' of std::wstring and what I found was this:
std::wstring moduleName Contains _String_val,
_String_val Contains _Container_base12,
_Container_base12 Contains _Myproxy
_Myproxy contains _Mycont. All valid values up to here.
But _MyCont then holds a _Myproxy value of 0xDDDDDDDD (Very similar to my access violation)
All other wstring's in my program contain valid values there, But for some reason once they leave angelscript that _Myproxy value gets messed up.
Tried it with stringpool enabled and disabled, no change in behavior.
Also, Here is my custom wstring code for angelscript (Well, Mainly its just a very simple port of the string code)