Interrogate crash

Hello everyone - this is my first time to use Panda, and the demos seem to work just fine on my computer. However, when trying to compile using “makepanda --everything”, I get a crash on the interrogate command containing “express_composite1.cxx express_composite2.cxx”. Using my debugger, it appears to be crashing in the “get_type” call from build… Unfortunately, I’m not familiar at all with the interrogator, and am having trouble determining exactly what is causing the crash. Is this a known bug, or did I somehow get a faulty download?

I’m using .NET 2005, and modified the makepanda to search for the MSVC8 directories. Might this be part of the problem?

Thanks in advance for any suggestions you may have for me.

I’ve never heard of this problem before. It might be related to changes with MSVC8, since every compiler is just a little bit different. If you post the exact error message, I might be able to help track down the problem.


Thanks for the quick response!

Unfortunately, the only error message I’m getting is “An unhandled win32 exception occured in interrogate.exe [1980].” The stack trace is as follows:

msvcr80.dll!_crt_debugger_hook(int _Reserved=)  Line 65
msvcr80.dll!_invoke_watson(const wchar_t * pszExpression=0x00000000, const wchar_t * pszFunction=0x00000000, const wchar_t * pszFile=0x00000000, unsigned int nLine=0, unsigned int pReserved=0)  Line 181 + 0x7 bytes
msvcr80.dll!_invalid_parameter_noinfo()  Line 99 + 0xc bytes
libdtoolconfig.dll!std::_String_const_iterator<char,std::char_traits<char>,std::allocator<char> >::operator+=(int _Off=1)  Line 175
libdtoolconfig.dll!GlobPattern::matches_substr ...  Line 187 + 0x3a bytes
libdtoolconfig.dll!GlobPattern::matches_substr ...  Line 203 + 0x30 bytes
libdtoolconfig.dll!ConfigPageManager::scan_up_from(Filename & result={...}, const Filename & dir={...}, const Filename & suffix={...})  Line 507 + 0x97 bytes
libdtoolconfig.dll!ConfigPageManager::scan_up_from(Filename & result={...}, const Filename & dir={...}, const Filename & suffix={...})  Line 533 + 0x10 bytes
msvcr80.dll!malloc(unsigned int size=33139400)  Line 163 + 0x63 bytes
msvcp80.dll!std::_Allocate<char>(unsigned int _Count=32561440, char * __formal=0x01f0d920)  Line 44 + 0x6 bytes
msvcr80.dll!free(void * pBlock=0x0089f5f4)  Line 115 + 0x5 bytes
libdtoolconfig.dll!ConfigPageManager::scan_auto_prc_dir(Filename & prc_dir={...})  Line 462 + 0x1c bytes
libdtoolconfig.dll!ConfigPageManager::reload_implicit_pages()  Line 189 + 0x17 bytes
libdtoolconfig.dll!ConfigVariableCore::get_declaration(int n=0)  Line 331 + 0x12 bytes
libdtoolconfig.dll!NotifyCategory::update_severity_cache()  Line 171 + 0x7d bytes
libdtoolconfig.dll!InterrogateDatabase::get_ptr()  Line 51 + 0x27 bytes
interrogate.exe!InterrogateBuilder::get_type(CPPType * type=0x018906f8, bool global=true)  Line 1745 + 0x2 bytes
interrogate.exe!InterrogateBuilder::build()  Line 233 + 0xc bytes
interrogate.exe!main(int argc=67, char * * argv=0x00bb5010)  Line 527
interrogate.exe!__tmainCRTStartup()  Line 586 + 0x17 bytes

My first thoughts were that it was a non-existent file, but they seem to all be in place. I’m really at a loss; tonight I’ll try it on my home computer with an older .NET version if I can’t seem to work it out today.


I’ve got the exact same problem. Did you find any solution yet?


Max Hajek

Debugging into the problem right now. It appears inside globpattern.cxx, GlobPattern::matches_substr(), the second time it is called. Here, the member field _pattern is “*.prc”, pi==pend and ci==cend, but pi!=ci.

The line 187:

if ((ci == cend) && (pi + 1 == pend) && (*pi) == '*')

is the culprit:
ci==end, thus the next expression (pi+1==pend) is evaluated, but pi+1 already points beyond the end of the string because pi==pend.

I’ll try to add a hack to workaround - let’s hope my late night (it’s 2.15 in the morning here in Vienna, Austria) and my general lack of sleep won’t make that a fatal adventure :wink:

Max Hajek


it seems to me that replacing

(pi + 1 == pend)


(1==std::distance(pi, pend))

should solve the problem - at least now interrogate continues to run where it crashed before.

As an aside, what’s the difference? And why did the original line work with all other compilers?
I suspect that all other compilers use an STL version which implements string iterators as char*. So pi + 1 is really pointer arithmetic and the original line is fine.
Now the STL shipped with VC8 probably (I did not check) implements string iterators differently. In general, with iterators it is not safe to assume they work like pointers. This is why there are the std::distance and std::advance functions.

Let’s see where we get.


Max Hajek

So far, makepanda runs nicely (apart from the occasional warning that certain functions are considered deprecated by MS latest compiler because they don’t check for buffer overruns).

Just in case here are the two patches for the changes I made.

    Enable use of Visual Studio 2005:
Index: makepanda/
RCS file: /cvsroot/panda3d/doc/makepanda/,v
retrieving revision 1.144
diff -u -r1.144
--- makepanda/	7 Jun 2006 17:38:33 -0000	1.144
+++ makepanda/	28 Aug 2006 23:39:08 -0000
@@ -574,25 +574,29 @@
 def LocateVisualStudio():
     # Try to use Visual Studio
-    vcdir = GetRegistryKey("SOFTWARE\\Microsoft\\VisualStudio\\7.1", "InstallDir")
+    vcdir = GetRegistryKey("SOFTWARE\\Microsoft\\VisualStudio\\8.0", "InstallDir")
+    vcSub= "vc"
+    if (vcdir == 0):
+	vcSub= "vc7"
+    	vcdir = GetRegistryKey("SOFTWARE\\Microsoft\\VisualStudio\\7.1", "InstallDir")
     if (vcdir == 0):
         vcdir = GetRegistryKey("SOFTWARE\\Microsoft\\VisualStudio\\7.0", "InstallDir")
     if (vcdir != 0) and (vcdir[-13:] == "\\Common7\\IDE\\"):
         vcdir = vcdir[:-12]
         WARNINGS.append("Using visual studio: "+vcdir)
-        AddToVisualStudioPath("PATH",    vcdir + "vc7\\bin")
+        AddToVisualStudioPath("PATH",    vcdir + vcSub + "\\bin")
         AddToVisualStudioPath("PATH",    vcdir + "Common7\\IDE")
         AddToVisualStudioPath("PATH",    vcdir + "Common7\\Tools")
         AddToVisualStudioPath("PATH",    vcdir + "Common7\\Tools\\bin\\prerelease")
         AddToVisualStudioPath("PATH",    vcdir + "Common7\\Tools\\bin")
-        AddToVisualStudioPath("INCLUDE", vcdir + "vc7\\ATLMFC\\INCLUDE")
-        AddToVisualStudioPath("INCLUDE", vcdir + "vc7\\include")
-        AddToVisualStudioPath("INCLUDE", vcdir + "vc7\\PlatformSDK\\include\\prerelease")
-        AddToVisualStudioPath("INCLUDE", vcdir + "vc7\\PlatformSDK\\include")
-        AddToVisualStudioPath("LIB",     vcdir + "vc7\\ATLMFC\\LIB")
-        AddToVisualStudioPath("LIB",     vcdir + "vc7\\LIB")
-        AddToVisualStudioPath("LIB",     vcdir + "vc7\\PlatformSDK\\lib\\prerelease")
-        AddToVisualStudioPath("LIB",     vcdir + "vc7\\PlatformSDK\\lib")
+        AddToVisualStudioPath("INCLUDE", vcdir + vcSub + "\\ATLMFC\\INCLUDE")
+        AddToVisualStudioPath("INCLUDE", vcdir + vcSub + "\\include")
+        AddToVisualStudioPath("INCLUDE", vcdir + vcSub + "\\PlatformSDK\\include\\prerelease")
+        AddToVisualStudioPath("INCLUDE", vcdir + vcSub + "\\PlatformSDK\\include")
+        AddToVisualStudioPath("LIB",     vcdir + vcSub + "\\ATLMFC\\LIB")
+        AddToVisualStudioPath("LIB",     vcdir + vcSub + "\\LIB")
+        AddToVisualStudioPath("LIB",     vcdir + vcSub + "\\PlatformSDK\\lib\\prerelease")
+        AddToVisualStudioPath("LIB",     vcdir + vcSub + "\\PlatformSDK\\lib")
     # Try to use the Visual Toolkit 2003
@@ -613,7 +617,7 @@
     # Give up
-    exit("Cannot locate Microsoft Visual Studio 7.0, 7.1, or the Visual Toolkit 2003")
+    exit("Cannot locate Microsoft Visual Studio 8.0, 7.0, 7.1, or the Visual Toolkit 2003")
 if (COMPILER == "MSVC7"):
  1. interrogate.cxx:
    Bugfix (hopefully I didn’t change the semantics):
    – Oops, I had the wrong patch pasted here. Corrected to contain the right patch (for the file panda3d/dtool/src/prc/globpattern.cxx:
< #include <iterator>
< 	  if ((ci == cend) && (1==std::distance(pi, pend)) && (*pi) == '*') {
>     if ((ci == cend) && (pi + 1 == pend) && (*pi) == '*') {

If I come up with further problems (which then might just as well be a result of my patches :wink:, I’ll post again in this thread. Otherwise, good night and good luck to everyone.

Max Hajek


I just got a compile error telling me:

\panda3d\panda\src\pgraph\loaderOptions.cxx : error C
4335: Mac file format detected: please convert the source file to either DOS or
UNIX format

I checked again whether I got the sources correctly from CVS, and CVS update (even forcing a clean copy) doesn’t make any difference, so the file sits in MAC-Format in CVS.
I converted it locally (and hope it won’t be hundreds more because then I need to find some batch converter :frowning:.
But you probably want to change this file in CVS, too, or maybe even add a converter tool in a cron job or something. (My CVS days are long gone, but shouldn’t it allow you to do some on-commit manipulation?)


Max Hajek

Now I get this error:

) : error C4430: missing type specifier - int assumed. Note: C++ does not suppor
t default-int

Looking at the line in question:

const NumResLims = (sizeof(MemRes)/sizeof(Memlimres));

it seems reasonably to change it to:

const int NumResLims = (sizeof(MemRes)/sizeof(Memlimres));

Next thing that hits me is a linker problem. The linker complains it cannot find libc.lib. After checking where it is and not (sic!) finding it, some web research turns out that VS2005 doesn’t come with any libc.lib anymore because support for the single-threaded runtime library has been dropped.

Let’s see what I’ll do about that…


Max Hajek


now I have a question I cannot seem to answer myself:

one proposed remedy for the libc problem is to add the linker swtich /NODEFAULTLIB:LIBC:LIB to the linker command. But for the life of it, I cannot find where the linker switches are generated.

Any pointer would be extremely welcome.

Many thanks,

Max Hajek

Frankly, I don’t understand why this fails to work on VC8. It’s true that you should not assume that iterators work like pointers; however, if the addition operator is defined for an iterator (as it is for the string iterator), then it sould be true that std::distance(pi, pi + 1) == 1. And it should equally be true that if std::distance(pi, pend) == 1, then pi + 1 == pend. Or what is the point of defining the addition operator at all, if this is not true?

It seems like a compiler or system library bug to me. Either that, or I’m really misunderstanding the nature of iterators. Still, I’ll be happy to make the suggested change.


Hi David,

I think the problem lies with the expression pi+1 (no matter whether inside eg std:.distance() or elsewhere): if pi already points to end(), incrementing it by any positive integer points to an undefined location. Now with real pointers that wouldn’t be a problem as the expression would basically just be an integer in disguise (as long as the pointer is not dereferenced). With iterators on the other hand we cannot assume that the increment operation doesn’t internally dereference something.
It seems to me (although I am too lazy to look it up :wink: ) that the standard says that in order to legally apply an increment operator to an iterator, the iterator must be dereferencable before the increment - which is not the case if we use an expression like pi+1 where pi already equals end().

Anyway, enough language theory - whenever I encounter something like this, I just think “Aha, interesting, another one of millions things to remember about c++” and go on. This is one of the reasons why I think that c++ doesn’t have a very long-term future. It’s just too full of little exceptions to the rule, and hard-to-predict under-the-covers machinery…

And one might argue that the popularity of Panda3d comes to a big part from the fact that it’s accessible via python - a language without these problems.

Cheers & thanks for your work,
Max Hajek

Ah, I believe you are right, even though I am also too lazy to look it up. :slight_smile: