Why is this segfaulting???

Started by
32 comments, last by jimi_hendrix 15 years, 4 months ago
Quote:Original post by jimi_hendrix
segfaults on IMG_Load()
The only way I can see that IMG_Load can fail (Except for a bug in sdl_image) is if filename is invalid. What happens if you printf() / cout filename.c_str() ?
Advertisement
Is IMG_Load() a macro or a function (I personally ever only used SDL_LoadBitmap(), afair)?

If a function, can you give us the output of
cout << reinterpret_cast <void*> (IMG_Load) << endl;
?
ok the previous code was so full of bugs and it was so messed up i started over...but i got another segfault :)

how would i read this backtrace to find out what line its on (im not good at looking at stuff like this)

(gdb) bt
#0 0x00007fb75915b5cb in SDL_DisplayFormat () from /usr/lib/libSDL-1.2.so.0
#1 0x0000000000400fd0 in loadImage (filename=
{static npos = 18446744073709551615, _M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x7fff615dfa60 "(\020�"}}, Red=255, Green=255, Blue=255)
at shooter.cpp:292
#2 0x00000000004012fa in Player (this=0x7fff615dfac0) at shooter.cpp:96
#3 0x0000000000401383 in Game (this=0x7fff615dfac0) at shooter.cpp:121
#4 0x000000000040108a in main (argc=1, args=0x7fff615dfbe8) at shooter.cpp:328

once i get past this little segfault ill be back where i was with cleaner code

heres the source

#include "SDL/SDL.h"#include <string>#include "SDL/SDL_image.h"#include "assert.h"//The attributes of the screen const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; const int SCREEN_BPP = 32; const int FRAMES_PER_SECOND = 30;SDL_Surface* screen = NULL;//prototypesSDL_Surface* loadImage(std::string filename, int Red, int Blue, int Green);void applySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination );//classesclass Timer{    private:    //The clock time when the timer started    int startTicks;        //The ticks stored when the timer was paused    int pausedTicks;        //The timer status    bool paused;    bool started;        public:    //Initializes variables    Timer();        //The various clock actions    void start();    void stop();    void pause();    void unpause();        //Gets the timer's time    int get_ticks();        //Checks the status of the timer    bool is_started();    bool is_paused();    };class Bullet{	public:		int x, y, velY;		SDL_Surface* image;		Bullet()		{			velY = 15;			image = loadImage("bullet.bmp", 0, 0, 0);		}		void fire(int X, int Y)		{			x = X;			y = Y;			applySurface(x, y, image, screen);		}		void update()		{			if (y >= 0)			{				y += velY;				applySurface(x, y, image, screen);			}		}};class Ship{};class Player{	public:	int x, y, velX;	SDL_Surface* ship;	  Player()	  {		  x = SCREEN_WIDTH / 2;		  y = SCREEN_HEIGHT - 70;		  velX = 5;		  		  ship = loadImage("player.bmp", 255, 255, 255);	  }	  void handleInput()	  {		Uint8 *keystates = SDL_GetKeyState( NULL );		if (keystates[SDLK_LEFT])		{			if (x > 0)			{				x -= velX;			}		}		if (keystates[SDLK_RIGHT])		{			if (x < SCREEN_WIDTH)			{				x += velX;			}		}	  }};class Game{	Player player;	Timer fps;		//SDL variables	SDL_Surface* playerShip;	SDL_Event event;		public:	 void init()	 {		//setup screen		SDL_Init(SDL_INIT_EVERYTHING);		screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );		SDL_WM_SetCaption("Space Shooter", NULL);		//load images and blit		applySurface(SCREEN_WIDTH / 2, SCREEN_HEIGHT - 70, player.ship, screen);				//enable repeats		SDL_EnableKeyRepeat(1, 5);		//flip the screen		SDL_Flip(screen);	 }	  void loop()	  {		bool quit = false;		while (quit == false)		{			while (SDL_PollEvent(&event))			{				if (event.type == SDL_QUIT)				{					quit =  true;				}				player.handleInput();				SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) );				applySurface(player.x, player.y, player.ship, screen);				SDL_Flip(screen);				//Cap the frame rate 				if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ) 				{ 					SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() ); 				} 			}		}	  }	  void close()	  {		SDL_FreeSurface(playerShip);		SDL_FreeSurface(screen);	  }};//Timer methodsTimer::Timer(){    //Initialize the variables    startTicks = 0;    pausedTicks = 0;    paused = false;    started = false;    }void Timer::start(){    //Start the timer    started = true;        //Unpause the timer    paused = false;        //Get the current clock time    startTicks = SDL_GetTicks();    }void Timer::stop(){    //Stop the timer    started = false;        //Unpause the timer    paused = false;    }void Timer::pause(){    //If the timer is running and isn't already paused    if( ( started == true ) && ( paused == false ) )    {        //Pause the timer        paused = true;            //Calculate the paused ticks        pausedTicks = SDL_GetTicks() - startTicks;    }}void Timer::unpause(){    //If the timer is paused    if( paused == true )    {        //Unpause the timer        paused = false;            //Reset the starting ticks        startTicks = SDL_GetTicks() - pausedTicks;                //Reset the paused ticks        pausedTicks = 0;    }}int Timer::get_ticks(){    //If the timer is running    if( started == true )    {        //If the timer is paused        if( paused == true )        {            //Return the number of ticks when the timer was paused            return pausedTicks;        }        else        {            //Return the current time minus the start time            return SDL_GetTicks() - startTicks;        }        }        //If the timer isn't running    return 0;    }bool Timer::is_started(){    return started;    }bool Timer::is_paused(){    return paused;    }//Game MethodsSDL_Surface* loadImage( std::string filename, int Red, int Green, int Blue ) { 	//The image that's loaded 	SDL_Surface* loadedImage = NULL; 		//The optimized image that will be used 	SDL_Surface* optimizedImage = NULL; 		//Load the image 	loadedImage = IMG_Load( filename.c_str() );	assert(loadedImage);	//If the image loaded 	if( loadedImage != NULL ) 	{ 		//Create an optimized image	       	assert(loadedImage);			optimizedImage = SDL_DisplayFormat( loadedImage ); 				//Free the old image 		SDL_FreeSurface( loadedImage );		//If the image was optimized just fine 		if( optimizedImage != NULL ) 		{ 			//Map the color key 			Uint32 colorkey = SDL_MapRGB( optimizedImage->format, Red, Green, Blue );			//Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent 			SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey ); 		}		 	//Return the optimized image 	}	       return optimizedImage; }void applySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination ) { 	//Make a temporary rectangle to hold the offsets       	SDL_Rect offset; 		//Give the offsets to the rectangle 	offset.x = x; 	offset.y = y; 	//Blit the surface 	SDL_BlitSurface( source, NULL, destination, &offset ); }int main(int argc, char* args[]){	Game game;	game.init();	game.loop();	game.close();	return 0;}
While debugging, sometimes the working directory is not the directory that the program is in. I am not familiar with gdb, but you should find out what it defaults the working directory to. Then, make sure that the image is inside of that directory.

Though this really shouldn't be the problem since IMG_Load is supposed to just return null if it can't load the file. The only reason I can think of for segfaulting is if the file is corrupted. Nonetheless, check the above if you haven't already.
Quote:Original post by jimi_hendrix
_M_dataplus = {<std::allocator<char>> = {<__gnu_cxx::new_allocator<char>> = {<No data fields>}, <No data fields>}, _M_p = 0x7fff615dfa60 "(\020�"}}, Red=255, Green=255, Blue=255)


That's some weird garbage where there should be the filename.

Does anything change if you use:
SDL_Surface* loadImage(const std::string & filename, int Red, int Blue, int Green);
or even
SDL_Surface* loadImage(const char * filename, int Red, int Blue, int Green);
now i get

g++ -Wall -g -ggdb -o test shooter.cpp -lSDL -lSDL_image
/tmp/ccyZweJU.o: In function `Player':
/home/vincent/programs/C++/shooter.cpp:96: undefined reference to `loadImage(std::basic_string<char, std::char_traits<char>, std::allocator<char> >, int, int, int)'
collect2: ld returned 1 exit status
make: *** [all] Error 1

when i sue char* filename...heres source

#include "SDL/SDL.h"#include <string>#include "SDL/SDL_image.h"#include "assert.h"//The attributes of the screen const int SCREEN_WIDTH = 640; const int SCREEN_HEIGHT = 480; const int SCREEN_BPP = 32; const int FRAMES_PER_SECOND = 30;SDL_Surface* screen = NULL;//prototypesSDL_Surface* loadImage(std::string filename, int Red, int Blue, int Green);void applySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination );//classesclass Timer{    private:    //The clock time when the timer started    int startTicks;        //The ticks stored when the timer was paused    int pausedTicks;        //The timer status    bool paused;    bool started;        public:    //Initializes variables    Timer();        //The various clock actions    void start();    void stop();    void pause();    void unpause();        //Gets the timer's time    int get_ticks();        //Checks the status of the timer    bool is_started();    bool is_paused();    };class Bullet{	public:		int x, y, velY;		SDL_Surface* image;		Bullet()		{			velY = 15;			image = loadImage("bullet.bmp", 0, 0, 0);		}		void fire(int X, int Y)		{			x = X;			y = Y;			applySurface(x, y, image, screen);		}		void update()		{			if (y >= 0)			{				y += velY;				applySurface(x, y, image, screen);			}		}};class Ship{};class Player{	public:	int x, y, velX;	SDL_Surface* ship;	  Player()	  {		  x = SCREEN_WIDTH / 2;		  y = SCREEN_HEIGHT - 70;		  velX = 5;		  		  ship = loadImage("player.bmp", 255, 255, 255);	  }	  void handleInput()	  {		Uint8 *keystates = SDL_GetKeyState( NULL );		if (keystates[SDLK_LEFT])		{			if (x > 0)			{				x -= velX;			}		}		if (keystates[SDLK_RIGHT])		{			if (x < SCREEN_WIDTH)			{				x += velX;			}		}	  }};class Game{	Player player;	Timer fps;		//SDL variables	SDL_Surface* playerShip;	SDL_Event event;		public:	 void init()	 {		//setup screen		SDL_Init(SDL_INIT_EVERYTHING);		screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );		SDL_WM_SetCaption("Space Shooter", NULL);		//load images and blit		applySurface(SCREEN_WIDTH / 2, SCREEN_HEIGHT - 70, player.ship, screen);				//enable repeats		SDL_EnableKeyRepeat(1, 5);		//flip the screen		SDL_Flip(screen);	 }	  void loop()	  {		bool quit = false;		while (quit == false)		{			while (SDL_PollEvent(&event))			{				if (event.type == SDL_QUIT)				{					quit =  true;				}				player.handleInput();				SDL_FillRect( screen, &screen->clip_rect, SDL_MapRGB( screen->format, 0, 0, 0 ) );				applySurface(player.x, player.y, player.ship, screen);				SDL_Flip(screen);				//Cap the frame rate 				if( fps.get_ticks() < 1000 / FRAMES_PER_SECOND ) 				{ 					SDL_Delay( ( 1000 / FRAMES_PER_SECOND ) - fps.get_ticks() ); 				} 			}		}	  }	  void close()	  {		SDL_FreeSurface(playerShip);		SDL_FreeSurface(screen);	  }};//Timer methodsTimer::Timer(){    //Initialize the variables    startTicks = 0;    pausedTicks = 0;    paused = false;    started = false;    }void Timer::start(){    //Start the timer    started = true;        //Unpause the timer    paused = false;        //Get the current clock time    startTicks = SDL_GetTicks();    }void Timer::stop(){    //Stop the timer    started = false;        //Unpause the timer    paused = false;    }void Timer::pause(){    //If the timer is running and isn't already paused    if( ( started == true ) && ( paused == false ) )    {        //Pause the timer        paused = true;            //Calculate the paused ticks        pausedTicks = SDL_GetTicks() - startTicks;    }}void Timer::unpause(){    //If the timer is paused    if( paused == true )    {        //Unpause the timer        paused = false;            //Reset the starting ticks        startTicks = SDL_GetTicks() - pausedTicks;                //Reset the paused ticks        pausedTicks = 0;    }}int Timer::get_ticks(){    //If the timer is running    if( started == true )    {        //If the timer is paused        if( paused == true )        {            //Return the number of ticks when the timer was paused            return pausedTicks;        }        else        {            //Return the current time minus the start time            return SDL_GetTicks() - startTicks;        }        }        //If the timer isn't running    return 0;    }bool Timer::is_started(){    return started;    }bool Timer::is_paused(){    return paused;    }//Game MethodsSDL_Surface* loadImage( char* filename, int Red, int Green, int Blue ) { 	//The image that's loaded 	SDL_Surface* loadedImage = NULL; 		//The optimized image that will be used 	SDL_Surface* optimizedImage = NULL; 		//Load the image 	loadedImage = IMG_Load( filename );	assert(loadedImage);	//If the image loaded 	if( loadedImage != NULL ) 	{ 		//Create an optimized image	       	assert(loadedImage);			optimizedImage = SDL_DisplayFormat( loadedImage ); 				//Free the old image 		SDL_FreeSurface( loadedImage );		//If the image was optimized just fine 		if( optimizedImage != NULL ) 		{ 			//Map the color key 			Uint32 colorkey = SDL_MapRGB( optimizedImage->format, Red, Green, Blue );			//Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent 			SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey ); 		}		 	//Return the optimized image 	}	       return optimizedImage; }void applySurface( int x, int y, SDL_Surface* source, SDL_Surface* destination ) { 	//Make a temporary rectangle to hold the offsets       	SDL_Rect offset; 		//Give the offsets to the rectangle 	offset.x = x; 	offset.y = y; 	//Blit the surface 	SDL_BlitSurface( source, NULL, destination, &offset ); }int main(int argc, char* args[]){	Game game;	game.init();	game.loop();	game.close();	return 0;}
You need to change the forward declaration of loadImage as well (the one on top).
Ahem.
Quote:
Is IMG_Load() a macro or a function (I personally ever only used SDL_LoadBitmap(), afair)?

If a function, can you give us the output of
cout << reinterpret_cast <void*> (IMG_Load) << endl;
?


The assert() after the IMG_Load() does nothing if IMG_Load() segv's. Also, make sure that at the point of #inclusion of assert NDEBUG isn't #defined.

Try out
assert (0 != reinterpret_cast <void*> (IMG_Load));
before the call to it.
no segfault but no image on screen either...all i did was change std::string to char* in the prototype and function

also i removed the .c_str() method in IMG_Load()...since there is no neeed for it with a char*
For the third time: Is IMG_Load != 0?

What I am trying to find out is that whether SDL did load the function properly or not. I may be in a big mistake here as I don't know the inner details of the SDL-Lib, but I am just trying to help someone here.

This topic is closed to new replies.

Advertisement