eddie at July 2nd, 2006 21:10 — #1
Generally, unresolved external symbols are easy to figure out, given a quick search on google, but I'm not having any luck with these in particular. I'm manually dumpbin-ing various directories to see where this could be (looks like something with the CRT?) but I'm not having any luck.
Anyone know where this is from?
utility.lib(Profiler.obj) : error LNK2019: unresolved external symbol __imp___invalid_parameter_noinfo referenced in function "public: bool __thiscall std::_Tree<class std::_Tmap_traits<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct Eddie::Profiler::ProfileHunk,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,struct Eddie::Profiler::ProfileHunk> >,0> >::const_iterator::operator==(class std::_Tree<class std::_Tmap_traits<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,struct Eddie::Profiler::ProfileHunk,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,struct Eddie::Profiler::ProfileHunk> >,0> >::const_iterator const &)const " (??8const_iterator@?$_Tree@V?$_Tmap_traits@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@UProfileHunk@Profiler@Eddie@@U?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@UProfileHunk@Profiler@Eddie@@@std@@@2@$0A@@std@@@std@@QBE_NABV012@@Z)
utility.lib(Memory.obj) : error LNK2001: unresolved external symbol __imp___invalid_parameter_noinfo
utility.lib(StreamProvider.obj) : error LNK2001: unresolved external symbol __imp___invalid_parameter_noinfo
game\build\untested\debug\test.exe : fatal error LNK1120: 1 unresolved externals
This error just showed up now when I did a clean build of my sources -- apparently one of my project settings was out of date, but wasn't reflected by my build system (grr.). As such, it could be anything I've done in the last several months.
The one thing I'm thinking is that it might have to do with me recompiling Lua to be C, not C++, and hence it's looking for a nonmangled entry for __imp__invalid_parameter_noinfo, when there's only a mangled version. I dunno.
Anyone know? Hopefully I'll find out on my own soon enough - but just curious if someone has this nugget stored in the back of their head.
eddie at July 2nd, 2006 23:01 — #2
Figured it out.
Somehow along the way, I started mixing release and debug versions of the CRT.
Apparently __imp__invalid_parameter_noinfo is a version of secure reporting for various CRT related functions. However this gets compiled in release, not debug, which is the problem I was experiencing.
Hope that helps someone else.
smokingrope at July 3rd, 2006 01:33 — #3
it will help somebody, i'm sure
kepler2 at August 10th, 2006 20:03 — #4
This seems to come from calls to Microsoft's VS2005 Standard Template Library (STL). I think this is still a derivative of Dinkumware. In my case, I cleared up the problem by removing a forced "undefine" of "_DEBUG" that was generated by VS2005 when it upgraded my project from VS .NET 2003. I suspect that the VS2005 STL generates runtime checks when code is compiled with the _DEBUG flag set. I suspect that when the _DEBUG flag is not set, the VS2005 STL relies on a call to a static entry point ("__imp___invalid_parameter_noinfo") that is not present in the debug runtimes. Bottom line - with STL, I suspect that NDEBUG/_DEBUG must match the runtime library that you compile for.
Hope this helps ...
eddie at August 10th, 2006 20:08 — #5
Wow, that's an old post to unearth.
Anyways, I'm not sure if you missed what I said earlier, but this happens from when you mix objects/libraries that use different builds of the runtime (debug versus release).
That's a *huge* problem, as you'll be running checks in some parts of code, and in others, not so much.
Maybe there's another corner case that you're incurring that I wasn't -- but I just recompiled all my libraries making sure I was using the correct /Mx flag (where x is D[d] or T[d]).
Hope that helps you out.
kepler2 at August 11th, 2006 16:03 — #6
I know for certain there's actually more to the problem than matching the runtime type (e.g. /MDd versus /MD) to the project. An automatic define of either "NDEBUG" or "_DEBUG" preprocessor variable is generated by the Visual Studio GUI. In my case, all of the runtime definitions matched the project type, HOWEVER when it converted my old Visual Studio project it forced an undefine of "_DEBUG" ("/U _DEBUG"). When I cleared the /U, everything was happy. I would call this a bug in the VS2005 STL ...
eddie at August 11th, 2006 16:07 — #7
/MDd Defines _DEBUG, _MT, and _DLL so that debug multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files. It also causes the compiler to place the library name MSVCRTD.lib into the .obj file.
Is that what you're talking about with the auto-inclusion of /D_DEBUG?
eddie at August 11th, 2006 16:08 — #8
Posted too fast.
Anyhow, as well as my above post (which is the only way I know of visual studio entering in _DEBUG to your code -- which technically isn't visual studio, but rather their compiler), I'm curious.
Why do you say that it's generated by the visual studio GUI, yet blame the STL?
kepler2 at August 11th, 2006 16:59 — #9
Why do you say that it's generated by the visual studio GUI, yet blame the STL?
Hard to say who's to blame without a fix in-hand, but it looks like the VS2005 STL is depending on a static method to handle new "invalid parameter" detection. If its a static method, then it only resides in the release runtimes. If it isn't a static method then the VS2005 is probably using different code for the same check (e.g. "#ifndef NDEBUG" versus "#ifdef _DEBUG"). If its a missing static entry point in the debug runtimes, then its an STL design bug. If the entry point is generated, then its an STL implementation error.
eddie at August 11th, 2006 20:56 — #10
The reason i think this points to a mixing of debug vs. release mixing in the CRT can be seen in the following two files from the 2005 STL sources:
#if !defined(_NATIVE_WCHAR_T_DEFINED) && defined(_M_CEE_PURE)
_CRTIMP void __cdecl _invalid_parameter(const wchar_t *, const wchar_t *, const wchar_t *, unsigned int, uintptr_t);
#else /* _DEBUG */
_CRTIMP void __cdecl _invalid_parameter_noinfo(void);
#endif /* def _DEBUG */
#define _SCL_SECURE_INVALID_PARAMETER(expr) ::_invalid_parameter(__STR2WSTR(#expr), __FUNCTIONW__, __FILEW__, __LINE__, 0)
#define _SCL_SECURE_INVALID_PARAMETER(expr) ::_invalid_parameter_noinfo()
So you can see that the define _SCL_SECURE_INVALID_PARAMETER in debug calls there _invalid_parameter function, while the release version calls what I presume to be a stub (_invalid_parameter_noinfo).
What was happening in my case was that I had compiled some libraries that were linking against the wrong runtime, so presumably some parts of the code were relying on the define from the release version, and rebuilding all my derivative libraries so they were all using the same setting cured it.
I don't think I'd call that a "bug" in the STL -- stubs for runtime are quite common in production software. That said, I don't know enough about your specific case/build setup to know where things might be going wrong.
kepler2 at August 14th, 2006 13:40 — #11
From the code you extracted, it looks like internationalization (UNICODE vs. MULTIBYTE charater set) is also implicated.
I think this is more a philosophical argument than practical. We both concur that the problem occurs by mixing code compiled for debug versus release. The only disagreement is the mechanism. I assure you that my failure actually had nothing to do with compiling against inconsistent runtimes. I can reproduce my failure simply by changing the existence of the "_DEBUG" preprocessor variable. The various projects in my solution were always compiled with consistent "/Mxx" flags. If you have inconsisent "/Mxx" flags, you will also have inconsistent use of "_DEBUG" versus "NDEBUG" versus nothing, right?
In VS6.0 and I think at least through VS .NET 2003, the GUI generated the _DEBUG definition, not the compiler. This means that the STL cannot depend on one of _DEBUG or NDEBUG being set (e.g. converted projects and NMAKE projects), so STL needs to deal with it. Therefore either the stub needs to be in all runtimes, or STL cannot use a runtime stub. I'm not saying the GUI should allow users to unset _DEBUG and NDEBUG, but I am saying that's a different topic. In either case, Microsoft isn't likely to address the issue for VS2005 anyway. For me, maybe it's time to go back to STLport.
Just one man's opinion ...