Runtime crash with text nodes

Using MSVC2008, building in release mode with current 1.7.0 release binaries.

I’ve followed along with C++ “hello world” example, and it works fine. However, if I try to put in Text nodes, it crashes, either at exit, or while running.

The code that is used is from the ported Ralph example doesn’t work.

TextNode* tn1 = new TextNode("text_1");
tn1->set_text("text1");
tn1->set_align(TextNode::A_right);
NodePath a1(window->get_aspect_2d().attach_new_node("a1"));
a1.attach_new_node(tn1);

With just this one node, it will show up, but when the program exits, it crashes with a corrupted heap problem. I’m able to “work around” this by changing the use of a1 to a pointer:

NodePath* a1=new NodePath(window->get_aspect_2d().attach_new_node("a1"));
a1->attach_new_node(tn1);

However, if I try to create and display a second text node, either with the pointer work-around or not, the program will crash in either framework.main_loop() or framework.do_frame(current_thread), depending on if I use one or the other.

TextNode* tn2 = new TextNode("text_2");
tn2->set_text("text2");
tn2->set_align(TextNode::A_right);
NodePath* a2=new NodePath(window->get_aspect_2d().attach_new_node("a2"));
a2->attach_new_node(tn2);

Any suggestions as to what I am doing wrong here?

Have you removed NDEBUG from the project settings?

Took it out, and it works now, but that doesn’t make any sense. The P3DActiveX.vcproj defines it, and the Python build readme also says using it is important to have it.

I did trace the problem down to within TextNode::Generate, but not beyond that. only happened so far with TextNodes, fwiw.

Tried building Panda3D as debug on a second machine and got pretty much nowhere.

Since NDEBUG looks to be used as a development-testing-flag-thing, it would be a good idea to have the header #pragma message if NDEBUG is set to catch this problem.

It is a bug in 1.7.0. It has already been fixed on the trunk; in future releases it will not be necessary to remove this setting.

For the record, NDEBUG is appropriate for “production-ready” releases: code that has been fully debugged and is ready to ship. It is never appropriate for code that you are still developing. Microsoft expects you to use the “Debug” project model for code that you are still developing, and then build a “Release” model when you are ready to ship.

This is a fine approach, but “Debug” adds a lot of other additional overhead which slows everything down considerably. That’s fine when you’re not building a 3-D application, or you don’t care too much about performance while you’re developing your application.

Panda is in an interesting position: we need to provide libraries that people can compile with while developing their applications. But people will also use these libraries to evaluate the performance of Panda; and many people will also use these same libraries for releasing their application. So if we provide “Debug” libraries, people will get an unfair impression of poor performance; and people who choose not to build their own Panda will be forced to release with poor performance.

This is why we provide “Release” libraries instead. But “Release” turns on NDEBUG by default, which makes it difficult to develop your code, because small mistakes will go undetected. So we compromise by providing “Release” libraries with NDEBUG disabled, which gives most of the full performance of Panda, but is still useful for development.

A fully robust solution would be to provide two (or three) different builds of Panda for C++ developers: one for Debug, one for Release without NDEBUG, and one for Release with NDEBUG. But then this just gets confusing to manage, both for us and for developers.

David

Okay, so NDEBUG, as used by the C++ standards, is/was designed to change how asserts are handled or compiled out. Using NDEBUG as something else, to make distinction between release builds and really-release builds, is what is causing the problems. Every other library I’ve ever seen & used never uses NDEBUG in this manner, if they ever use it at all. It’s either #ifdef _DEBUG or nothing.

Assuming that your customers are not able to distinguish between a release product and a debug, and forcing them to not be able to debug any problems and encounter really weird crashes with default settings is a non-optional deployment path. Black-box debugging is simply not an option; if we wanted that, we’d choose closed-source and be done with it.

The solution would be to either provide debug & release builds (with out-of-the-box support for default MS project settings), or make it so that the makepanada build actually makes working debug builds, will all parts needed to make said builds. Or just drop C++ support entirely and focus exclusively on Python.

As I’ve said, there’s already a fix on the trunk, which removes the dependency on the external setting of NDEBUG. The fact that it slipped into 1.7.0 with this dependency is an unfortunate mistake.

The handling of asserts is indeed the difference between NDEBUG and not NDEBUG.

I agree that providing a debuggable library is critical. Fortunately, a release build is in fact fully debuggable.

David