# Segmentation fault in simple crystal space program

## Recommended Posts

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)
return true;
}
return false;
}

int main(int argc, char const* argv[]) {
csRef<iEngine> engine;
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_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;
}

csReport (object_reg, CS_REPORTER_SEVERITY_ERROR,
"crystalspace.application.simple",
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
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;
}


##### Share on other sites
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).

##### Share on other sites
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.

##### Share on other sites
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]

##### Share on other sites
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.)

##### Share on other sites
Quote:
 Original post by clumThe 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

##### Share on other sites
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.

##### Share on other sites
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]

##### Share on other sites
Well, I worked out the g2d one:
Quote:
 From the same HOWTOIf 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.

##### Share on other sites
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.

##### Share on other sites
I normally use csRef for anything I grab from CS like iGraphics2D. It is the safest way to prevent memory leaks. The easiest way to check stuff like that is to call

object->GetRefCount() to see how many things are accessing it.

If at the end you keep getting stuff like "Unreleased references" you can use the GetRefCount() to track them down ( painful sometimes ).

The example you show with iSector is ok since it is just a plain pointer so unless you do an IncRef on it you don't need a DecRef.

Edit: Update with correct info :)
---------
Andrew

[Edited by - acraig on July 8, 2004 9:06:28 AM]

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628306
• Total Posts
2981948

• 10
• 11
• 12
• 11
• 10