Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SDL_LoadFile() Linux segmentation fault reading datasize #5394

Closed
logos-maker opened this issue Mar 10, 2022 · 8 comments
Closed

SDL_LoadFile() Linux segmentation fault reading datasize #5394

logos-maker opened this issue Mar 10, 2022 · 8 comments
Labels
invalid This doesn't seem right

Comments

@logos-maker
Copy link

logos-maker commented Mar 10, 2022

When reading the length pointed to to get the datasize, I get a segmentation fault. This only seams to occur if I have a path for the file, but not if the file is in the working directory. But I can still read the data from the file but not get the length as I will get a segmentation fault. So I can read the pointer but not the length that it points to.

It looks like my system is using version 2.0.10

@1bsyl
Copy link
Contributor

1bsyl commented Mar 14, 2022

@logos-maker
do you have a test case ?

@sezero sezero added the waiting Waiting on user response label Mar 26, 2022
@sezero
Copy link
Contributor

sezero commented Mar 26, 2022

I tried with the following, can't get a segfault. Must see the particular test case from @logos-maker

#include "SDL.h"
#include <stdio.h>

int main (int argc, char **argv) {
  SDL_RWops *rw;
  void *loaded;
  size_t sz;

  if (argc != 2) {
    return 1;
  }
  rw = SDL_RWFromFile(argv[1], "rb");
  if (!rw) {
    fprintf(stderr, "Failed opening %s\n", argv[1]);
    return 1;
  }
  loaded = SDL_LoadFile_RW(rw, &sz, 1);
  if (!loaded) {
    fprintf(stderr, "Failed loading from %s\n", argv[1]);
    return 1;
  }
  SDL_free(loaded);
  fprintf(stderr, "DATASIZE: %lu\n", (unsigned long)sz);
  return 0;
}

@logos-maker
Copy link
Author

logos-maker commented Apr 5, 2022

The code by sezero gives the size even if it isn't a file in the same directory as the program. So it works fine.
But the problem is with SDL_LoadFile() not SDL_LoadFile_RW so I changed that code to reflect that by the following...

#include "SDL2/SDL.h"
#include <stdio.h>

int main (int argc, char **argv) {
  void *loaded;
  size_t *sz;

  if (argc != 2) {
    return 1;
  }
  loaded = SDL_LoadFile(argv[1], sz);
  if (!loaded) {
    fprintf(stderr, "Failed loading from %s\n", argv[1]);
    return 1;
  }
  SDL_free(loaded);
  fprintf(stderr, "DATASIZE: %lu\n", (unsigned long)*sz);
  return 0;
}

...but that didn't give the segmentation fault. But the same code still gives a segmentation fault if I have a window open and drops a file on the window. I'm not sure whats happening. I'll have some code that I will post that recreates the problem. Or is the code above faulty, but gives the right result by some fluke?

@logos-maker
Copy link
Author

The code bellow recreates the problem. And then it also gives a segmentation fault if you give a file name in the terminal. So that's strange.

#include "SDL2/SDL.h"
#include <stdio.h>

int main (int argc, char **argv) {
  void *loaded;
  size_t *sz;

  if (argc == 2) {
	  loaded = SDL_LoadFile(argv[1], sz);
	  if (!loaded) {
	    fprintf(stderr, "Failed loading from %s\n", argv[1]);
	    return 1;
	  }
	  SDL_free(loaded);
	  fprintf(stderr, "DATASIZE: %lu\n", (unsigned long)*sz);
	  return 0;
  }
	SDL_Window *window;
	SDL_Renderer *renderer;
	SDL_Event event;

	if (SDL_Init(SDL_INIT_VIDEO) < 0) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
		return 3;
	}

	if (SDL_CreateWindowAndRenderer(256,256, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
		SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window and renderer: %s",SDL_GetError());
		return 3;
	}
	while (1) {
		while( SDL_PollEvent( &event ) ){	// drain all events in que for SDL2
			switch( event.type ){
				case  SDL_QUIT:
					goto end_program;
				break;
				
				case SDL_DROPFILE:
					if(!(loaded = SDL_LoadFile(event.drop.file,sz))){
						SDL_Log("could not load file\n");
					};
					SDL_Log("%s",event.drop.file);
					SDL_Log("DATASIZE: %lu\n",(unsigned long)*sz);
					SDL_SetWindowTitle(window, strcat("test", event.drop.file));

					SDL_free(event.drop.file);
				break;
			}
		}

		SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
		SDL_RenderClear(renderer);

		SDL_RenderPresent(renderer);
		SDL_Delay(16);
	}
	end_program:
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
}

@sezero sezero added the invalid This doesn't seem right label Apr 5, 2022
@sezero
Copy link
Contributor

sezero commented Apr 5, 2022

Your test code is definitely wrong:

1.c: In function 'main':
1.c:11:12: warning: 'sz' may be used uninitialized in this function [-Wmaybe-uninitialized]
     loaded = SDL_LoadFile(argv[1], sz);
            ^

$ ./a.out /home/sezero/.gitconfig
Segmentation fault (core dumped)

What you want is this:

#include "SDL.h"
#include <stdio.h>

int main (int argc, char **argv) {
    void *loaded;
    size_t sz;

    if (argc != 2) {
        return 1;
    }
    loaded = SDL_LoadFile(argv[1], &sz);
    if (!loaded) {
        fprintf(stderr, "Failed loading from %s\n", argv[1]);
        return 1;
    }
    SDL_free(loaded);
    fprintf(stderr, "DATASIZE: %lu\n", (unsigned long)sz);
    return 0;
}

... which works just fine:

$ ./a.out /home/ozzie/.gitconfig
DATASIZE: 110

Closing as invalid.

@sezero sezero closed this as completed Apr 5, 2022
@sezero sezero removed the waiting Waiting on user response label Apr 5, 2022
@logos-maker
Copy link
Author

What sezero says is the way to do it doesn't even compile.

test.c: In function ‘main’:
test.c:11:34: warning: passing argument 2 of ‘SDL_LoadFile’ makes pointer from integer without a cast [-Wint-conversion]
   11 |   loaded = SDL_LoadFile(argv[1], sz);
      |                                  ^~
      |                                  |
      |                                  size_t {aka long unsigned int}
In file included from /usr/include/SDL2/SDL_audio.h:36,
                 from /usr/include/SDL2/SDL.h:36,
                 from test.c:1:
/usr/include/SDL2/SDL_rwops.h:251:31: note: expected ‘size_t *’ {aka ‘long unsigned int *’} but argument is of type ‘size_t’ {aka ‘long unsigned int’}
  251 | extern DECLSPEC void *SDLCALL SDL_LoadFile(const char *file, size_t *datasize);
      |                               ^~~~~~~~~~~~

@sezero
Copy link
Contributor

sezero commented Apr 5, 2022

Look carefully at how I define sz and pass it to SDL_LoadFile.

@logos-maker
Copy link
Author

Thanks!!!
Maybe the corrected code given by sezero could be used as an example in the wiki at wiki.libsdl.org

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
invalid This doesn't seem right
Projects
None yet
Development

No branches or pull requests

3 participants