Segmentation fault in simple crystal space program

Started by
9 comments, last by acraig 19 years, 9 months ago
So, for all of you proffessed CS experts: I tried following one of CS's tutorials. I basically copied and pasted the code, but leaving out all the fancy OOP stuff. But I get a segmentation fault when I hit escape gdb says the segmentation fault is taking place in ~csRef(). What did I do wrong? Here's the code:

#include "cssysdef.h"
#include "csutil/sysfunc.h"
#include "iutil/vfs.h"
#include "csutil/cscolor.h"
#include "cstool/csview.h"
#include "cstool/initapp.h"
#include "iutil/eventq.h"
#include "iutil/event.h"
#include "iutil/objreg.h"
#include "iutil/csinput.h"
#include "iutil/virtclk.h"
#include "iengine/sector.h"
#include "iengine/engine.h"
#include "iengine/camera.h"
#include "iengine/light.h"
#include "iengine/texture.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/material.h"
#include "imesh/thing.h"
#include "imesh/object.h"
#include "ivideo/graph3d.h"
#include "ivideo/graph2d.h"
#include "ivideo/texture.h"
#include "ivideo/material.h"
#include "ivideo/fontserv.h"
#include "igraphic/imageio.h"
#include "imap/parser.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "csutil/cmdhelp.h"
#include "csutil/event.h"

CS_IMPLEMENT_APPLICATION

iObjectRegistry* object_reg;

bool HandleEvent (iEvent& ev)
{
  if (ev.Type == csevKeyboard && 
    csKeyEventHelper::GetEventType (&ev) == csKeyEventTypeDown &&
    csKeyEventHelper::GetCookedCode (&ev) == CSKEY_ESC)
  {
    csRef<iEventQueue> q (CS_QUERY_REGISTRY (object_reg, iEventQueue));
    if (q)
      q->GetEventOutlet()->Broadcast (cscmdQuit);
    return true;
  }
  return false;
}

int main(int argc, char const* argv[]) {
    csRef<iEngine> engine;
    csRef<iLoader> loader;
    csRef<iGraphics3D> g3d;
    csRef<iKeyboardDriver> kbd;
    csRef<iVirtualClock> vc;

    object_reg =
    csInitializer::CreateEnvironment (argc, argv);

    if (!csInitializer::RequestPlugins (object_reg,
					CS_REQUEST_VFS,
					CS_REQUEST_OPENGL3D,
					CS_REQUEST_ENGINE,
					CS_REQUEST_FONTSERVER,
					CS_REQUEST_IMAGELOADER,
					CS_REQUEST_LEVELLOADER,
					CS_REQUEST_REPORTER,
					CS_REQUEST_REPORTERLISTENER,
					CS_REQUEST_END)) {
	csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
		  "crystalspace.application.simple",
		  "Can't initialize plugins!");
	throw 1;
    }

    if (!csInitializer::SetupEventHandler(object_reg, HandleEvent)) {
	
	csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
		  "crystalspace.application.simple",
		  "Can't initialize event handler!");
	throw 1;
    }
    
    // Check for commandline help.
    if (csCommandLineHelper::CheckHelp (object_reg)) {
	
	csCommandLineHelper::Help (object_reg);
	throw 1;
    }

    // The virtual clock.
    vc = CS_QUERY_REGISTRY (object_reg, iVirtualClock);
    if (!vc) {
	csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
		  "crystalspace.application.simple",
		  "Can't find the virtual clock!");
	throw 1;
    }

    // Find the pointer to engine plugin
    engine = CS_QUERY_REGISTRY (object_reg, iEngine);
    if (!engine) {
	csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
		  "crystalspace.application.simple",
		  "No iEngine plugin!");
	throw 1;
    }

    loader = CS_QUERY_REGISTRY (object_reg, iLoader);
    if (!loader) {
	csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
		  "crystalspace.application.simple",
		  "No iLoader plugin!");
	throw 1;
    }

    g3d = CS_QUERY_REGISTRY (object_reg, iGraphics3D);
    if (!g3d) {
	csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
		  "crystalspace.application.simple",
		  "No iGraphics3D plugin!");
	throw 1;
    }
    
    kbd = CS_QUERY_REGISTRY (object_reg, iKeyboardDriver);
    if (!kbd) {
	csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
		  "crystalspace.application.simple",
		  "No iKeyboardDriver plugin!");
	throw 1;
    }

    // Open the main system. This will open all the previously
    // loaded plug-ins.
    if (!csInitializer::OpenApplication (object_reg)) {
	csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
		  "crystalspace.application.simple",
		  "Error opening system!");
	throw 1;
    }
    
    csReport (object_reg, CS_REPORTER_SEVERITY_NOTIFY,
	      "crystalspace.application.simple",
	      "Simple Crystal Space Application version 0.1.");

    csDefaultRunLoop (object_reg);
    csInitializer::DestroyApplication (object_reg);
    return 0;
}
Zorx (a Puzzle Bobble clone)Discontinuity (an animation system for POV-Ray)
Advertisement
Oh - I just realised - I have slightly more information: The segfault is happenning in csRef<iGraphics3d>::~csRef. Also, the tutorial claims that its supposed to be a blank screen, but I actually get bits and pieces from old runs of crystal space programs (particularly walktest).
Zorx (a Puzzle Bobble clone)Discontinuity (an animation system for POV-Ray)
As an experiment, I tried following the next stage of the tutorial, where you're supposed to draw something, and it came up with a new segfualt, this time directly in main(). I would try compiling with more debugging information to find out exactly where it is, but I have to go now and I'd imagine it is somewhere around when the iGraphics object is first referenced.
Zorx (a Puzzle Bobble clone)Discontinuity (an animation system for POV-Ray)
You get this problem because you left out the "fancy OOP stuff":

Before you call csInitializer:: DestroyApplication, you have to make sure you released all your references to CS' internal system such as iGraphics3D, iKeyboard etc. In the tutorial, all csRefs are members of the class Simple, so the following code will make sure all references are released before the call to DestroyApplication:

  delete simple; // Release engine, loader, g3d, kbd, vc  simple = 0;  csInitializer::DestroyApplication (object_reg);


Solution: change the end of main () to:
  csDefaultRunLoop (object_reg);  // add this  engine = NULL;  loader = NULL;  g3d = NULL;  kbd = NULL;  vc = NULL;		  csInitializer::DestroyApplication (object_reg);  return 0;


You might also want to read CS Manual: HOWTO Smart Pointers , especially the last paragraph.

edit: changed the CS Manual link to point to the online docs instead of my harddrive

[Edited by - Erluk on July 7, 2004 9:09:24 AM]
Problems with Windows? Reboot! - Problems with Linux? Be root!
Thanks, that worked. I'm just a bit concerned that the tutorial I read said that I should see a blank screen while I'm seeing gibberish, but hopefully its just that the author of the tutorial had a video card that clears its memory first.

The link you gave is a link to a file on your hard drive, though[grin]. I'm sure I'll manage to find it on mine, though (I don't even have a C:\ drive. In fact, that would be an illegal drive specification in my operating system.)
Zorx (a Puzzle Bobble clone)Discontinuity (an animation system for POV-Ray)
Quote:Original post by clum
The link you gave is a link to a file on your hard drive, though[grin].


Whoops, that's why you shouldn't have online and offline documentation opened at the same time... [rolleyes]

Anyway, this should be the correct link: CS Online(!) Manual
Problems with Windows? Reboot! - Problems with Linux? Be root!
In other words, I should just put all of my objects into a class and call csInitializer::DestroyApplication() from somewhere else (like main()). That's fine with me, because I normally use classes heavily, its just that I saw no point in such a simple program.
Zorx (a Puzzle Bobble clone)Discontinuity (an animation system for POV-Ray)
Another quick question: The tutorial I was reading has something really strange - it uses a iSector * instead of a csRef<iSector>. Is this intentional? It also doesn't appear to delete or csDecRef it anywhere. That doesn't sound right. Is this a mistake or just something I don't understand. EDIT: There's another, similar pointer in the next stage of the tutorial, too:
iGraphics2D* g2d = g3d->GetDriver2D ();view->SetRectangle (0, 0, g2d->GetWidth (), g2d->GetHeight ());


[Edited by - clum on July 7, 2004 10:05:01 AM]
Zorx (a Puzzle Bobble clone)Discontinuity (an animation system for POV-Ray)
Well, I worked out the g2d one:
Quote:From the same HOWTO
If you do not need to own a reference to a reference-counted object, and you know positively that the object will exist for the duration of a piece of code, then you can use a plain pointer rather than a smart pointer.
I'm still suspicious about that iSector *, though.
Zorx (a Puzzle Bobble clone)Discontinuity (an animation system for POV-Ray)
Perhaps it was just an oversight. But I can't really help you there; maybe one of the CS developers that lurk on these boards knows more... or you could ask on the crystal-main mailing list.
Problems with Windows? Reboot! - Problems with Linux? Be root!

This topic is closed to new replies.

Advertisement