• 10
• 10
• 12
• 12
• 14

# debugger issues

This topic is 4226 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am working on the framework for a game. At the moment, I am stuck on the graphics system. I am loading and displaying text instead of graphics because it will use the same framework as graphics, but be easier to debug and think out. When the problem occoured, I isolated the graphics into it's own system, trying to simplify, but the problem kept occuring. I'll post the code at the end for reference. The first problem I observed was that the program get's stuck after printing the initialization messages for display. when I run it through the debugger, the blasted thing segfaults, and dumps random charachters all over the screen and makes the system bell beep repeatedly. I found that it crashed on the call to graphics->draw(renderable). I traced into this, and the next line was the same line, and the one after that was in the middle of display::getmodel(string filename). My question is this: why doesn't that trace end up at the beginning of display::draw? graphics.cpp
#include "graphics.h"
#include <iostream>
#include <fstream>
using namespace std;

class model /*Did I do this right? I put this here becaus enothing outside of graphics needs to know it exists.*/
{
protected:
string image;
public:
friend int display::draw(renderable r);
//    std::string getdata() {return image;}
};

display::display()
{
cout<<"Graphics: Initializing..."<<endl;
cout<<"Graphics: Initialized"<<endl;
}

display::~display()
{
cout<<"Graphics: shut down"<<endl;
}

int display::draw(renderable r)
{
cout<<"drawing..."<<endl;
string m;
m = r.image->image;
cout<<m<<endl;
}
int display::draw()
{
cout<<"object drawn"<<endl;
}

boost::shared_ptr<model> display::getmodel(string filename)
{

if (modelmap.find(filename) != modelmap.end())
{
return modelmap[filename];
}
else
{
modelmap[filename] = boost::shared_ptr<model>(new model);
if (modelmap[filename].get() != NULL)
{
boost::shared_ptr<model> m = modelmap[filename];
return modelmap[filename];
}
else
{
cout<<"Failed to get model"<<endl;
boost::shared_ptr<model> p;
p.reset();
return p;
}
}
}

renderable::renderable()
{
//null and useless rendable
}
renderable::renderable(boost::shared_ptr<display> disp, string filename)
{
image = disp->getmodel(filename);
parent = disp;
position = 0;   //placeholders. change these to be meaningful according to whatever physics system gets implemented.
orientation = 0;
}

{
fstream file;
file.open(filename.c_str());
if (!file.is_open())
{
cout<<"Failed to open "<<filename<<endl;
boost::shared_ptr<model> p;
p.reset();
return p;
}
file>>image;    //placeholder untill graphics gets real.
return boost::shared_ptr<model> (this);
}
/*test main*/
main()
{
boost::shared_ptr<display> graphics;
graphics = boost::shared_ptr<display>(new display);

std::string str = "(<?>)";

renderable r(graphics, "command-module.txt");
graphics->draw(r);
int i;
cin>>i;
}


graphics.h
#ifndef GRAPHICS_H
#define GRAPHICS_H

#include <boost/shared_ptr.hpp>
#include <string>
#include <map>
class renderable;
class model;

class display
{
private:
std::map<std::string, boost::shared_ptr<model> > modelmap;

public:
display();
~display();
int draw(renderable r);
boost::shared_ptr<model> getmodel(std::string filename);
};

class renderable /*a renderable will be altered by a module and then passed to the graphics system for rendering.*/
{
protected:
boost::shared_ptr<model> image;
boost::shared_ptr<display> parent;
int position;
int orientation;
public:
friend int display::draw(renderable r);
renderable();
renderable(boost::shared_ptr<display> disp, std::string filename);
};

/* each model doesn't know about the rest of the program; it just knows how to
load from a file. display keeps track of models, and draw them.*/

#endif /*GRAPHICS_H*/


[Edited by - NIm on September 28, 2006 11:12:45 PM]

##### Share on other sites
Random observations:
• In display::draw, you should use a reference to the string. This will avoid the overhead of copying the string from image into the m temporary local variable. Even better, use a const reference.

• In display::getmodel, if the loading fails, you're returning a random garbage pointer. This is a very bad idea. Return a null pointer instead (0). You do this again in model::load.

• Your default constructor for renderable is a bit shaky. If an uninitialized renderable object is never meaningful, you should remove the default constructor so that the disp and filename parameters must be provided to construct a renderable (best option). Failing that, at least initialize the members to null pointers so you don't have to worry about garbage pointers causing trouble.

• Friends are not a good solution in this case. Have renderable implement a function render which you pass a Display& to in order to accomplish rendering. Using a friend function violates encapsulation and adds unnecessary coupling between your modules.

• You are using std::map's [] operator incorrectly. When using [], if the given key does not exist in the map, a new record is inserted by calling the default constructor of the data type. For a shared_ptr, this is bad news - yet another garbage pointer is being introduced into your code.

I don't have time to try compiling and running your code, but I'd recommend fixing up the garbage-pointer issues first. That will rule out potential gremlins that are making your debugging excessively difficult. Based on your description of the symptoms, I would guess that you're trying to dereference a string (r.image->image) given a bogus pointer. I'm 90% certain that your crash originates from at least one of the pointer problems I outlined above.

Good luck with your debugging [smile]

##### Share on other sites
How do I set a boost shared_ptr to null? I looked for it in the documentation, but it wasn't apparent.

##### Share on other sites
shared_ptr::reset();.

jfl.

##### Share on other sites
Thanks. I fixed those things, except for what you said about friend being evil, and did a bit more with the debugger. I found that the jumping around is part of boost, and I have to endure ablot of jumping around in boost, but I eventually get where I'm supposed to be, in display::getmodel. From there, it goes into model::load, as it should. Just before this function returns, I find that this->image constains the contents of the file, as it should. however, after it returns, back up in display::getmodel, I find that the returned model does not contain the correct string, despite the addresses being the same. This seems impossible to me. I just don't know what to do.

I've updated the source listing at the top ot reflect the changesx I made to my code.

EDIT: I found that the pointer returned by modelmap[filename]->load was not the same as the value of modelmap[filename]. I htink they should be the same, because modelmap[filename] returns a pointer to itself. Why is this not the case?

[Edited by - NIm on September 28, 2006 11:50:14 PM]

##### Share on other sites
After a huge amount of stuckness and failed comprehension, I decided to solve this the evil, tupid, foolish way: cargo cult programming. I rewrote it, and it worked, but I don't like doing that kind of silliness. I learned an important lesson though: always check a function after you write it. Always test it's behavior, so it's easier to see when you screw up, and where.

Anyway, I had several remaining questions. The first: What can I do to make it easier for people to help me? I noticed that I didn't get as much of the typical gamedev friendly helpfulness as usual. Was this because I posted so much code?

What other ways can I solve my problems?

Lastly, the obvious: I solved my problem, but I don't know how. What was wrong with my original code?