C/SDL - Segmentation fault when program run multiple times in succession [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I've encountered some strange behaviour in my program.
When I run my program 3-4 times and close it immediately, it's starting to give me segmentation faults before it even starts. When I haven't opened it for a while it opens the first 2-3 times without problem and then again seg faults.
I am open to suggestion on what can cause this kind of problem.
The project is quite big so I don't know where exactly to look so if someone wants to see the source code, here you go :
https://github.com/rokn/Helsys3

Let me break down a debugging session for you, but in future you better do that yourself.
If the problem can be easily reproduced, it is quite trivial to fix it:
gdb ./GAME
(gdb) r
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7b2d10c in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0
(gdb) bt
#0 0x00007ffff7b2d10c in ?? () from /usr/lib/x86_64-linux-gnu/libSDL2-2.0.so.0
#1 0x000000000040650c in sprite_free_age ()
#2 0x00000000004065f9 in AGE_SpriteLoad ()
#3 0x0000000000402740 in BattlefieldLoad () at battlefield.c:89
#4 0x0000000000402794 in BattlefieldInit (battlefield=0x1dca440, battlefieldId=1)
at battlefield.c:96
#5 0x0000000000405349 in BattleInitialize (leftTeam=0x60dff0 <leftTeam>,
rightTeam=0x60e010 <rightTeam>, battlefieldId=1) at battle.c:13
#6 0x0000000000401e8f in LoadContent () at main.c:90
#7 0x0000000000401d2b in main (argc=1, argv=0x7fffffffdfc8) at main.c:49
It crashed within SDL, and last thing that called it is sprite_free_age. What's here (AGE/AGE_Sprite.c):
void sprite_free_age(AGE_Sprite *sprite)
{
if( sprite->texture != NULL )
{
SDL_DestroyTexture( sprite->texture );
sprite->texture = NULL;
sprite->Width = 0;
sprite->Height = 0;
}
}
The only SDL call is SDL_DestroyTexture, and NULL check is performed, which means sprite have garbage data (not NULL but still not an SDL texture but rather something else). It was called from AGE_SpriteLoad:
bool AGE_SpriteLoad(AGE_Sprite *sprite, char *path)
{
sprite_free_age(sprite);
SDL_Texture *finalTexture = NULL;
SDL_Surface *loadedSurface = IMG_Load(path);
// ... the rest is omitted
So whenever you call AGE_SpriteLoad, it first tries to drop previous sprite it may've contained. It was called from BattlefieldLoad at battlefield.c:89:
void BattlefieldLoad()
{
assert(AGE_SpriteLoad(&squareWalkable, "Resources/Battlefield/SquareWalkable.png"));
assert(AGE_SpriteLoad(&squareSelected, "Resources/Battlefield/SquareSelected.png"));
assert(AGE_SpriteLoad(&squareEnemy, "Resources/Battlefield/SquareEnemy.png"));
assert(AGE_SpriteCreateBlank(&battlefieldField, LevelWidth, LevelHeight, SDL_TEXTUREACCESS_TARGET));
AGE_ListInit(&objectsList, sizeof(AGE_Sprite));
AGE_Sprite objectSprite;
int i;
char buffer[100];
for (i = 0; i < BATTLEFIELD_OBJECTS_COUNT; ++i)
{
snprintf(buffer, sizeof(buffer), "Resources/Battlefield/Object_%d.png", i+1);
AGE_SpriteLoad(&objectSprite, buffer);
AGE_ListAdd(&objectsList, &objectSprite);
}
}
Here you have uninitialised AGE_Sprite objectSprite, and you're calling AGE_SpriteLoad on it, which tries to drop old data (which is uninitialised => garbage) and (maybe) crashes. First thing coming to mind is that you need to set objectSprite to zero-bytes, either with memset or just by initialising it upon declaration, e.g. AGE_Sprite objectSprite = {};.

Related

Program crashing only when not run through gdb

I asked a question earlier about this program and was able to resolve it--the good news is my program is working now! The bad news is that it only works when I run it through gdb. Whenever I normally compile the program it'll crash, but running it through gdb gives correct output and allows it to exit normally.
I read Dennis Yurichev's post on debugging this sort of problem with the stack or something in gdb, but I'm still pretty new to programming so I have no idea what I am doing.
Here is the output from attaching gdb to the process ID of the program and then dumping the stack:
Breakpoint 1, 0x74337480 in OutputDebugStringA () from C:\WINDOWS\SysWOW64\KernelBase.dll
(gdb) bt
#0 0x74337480 in OutputDebugStringA () from C:\WINDOWS\SysWOW64\KernelBase.dll
#1 0x77478a64 in msvcrt!_invalid_parameter () from C:\WINDOWS\SysWOW64\msvcrt.dll
#2 0x77425a20 in wctype () from C:\WINDOWS\SysWOW64\msvcrt.dll
#3 0x00010001 in ?? ()
#4 0x77493a09 in msvcrt!fscanf_s () from C:\WINDOWS\SysWOW64\msvcrt.dll
#5 0x7749399b in msvcrt!fscanf () from C:\WINDOWS\SysWOW64\msvcrt.dll
#6 0x00401d0d in main () at ZigSort.c:377
I think it's saying it's crashing due to invalid input or something from fscanf, but that doesn't make sense...
The line referenced (main() line 377) is the first fscanf in here:
int main(void)
{
//initializing file pointer
FILE * ifp;
ifp = fopen("zigzag.txt", "r");
int n;
//getting number of values
fscanf(ifp, "%d", &n); //**LINE 377 RIGHT HERE**
//reading values into a queue
queue_t * data = queue_create();
int ipt;
for(int i=0; i<n; i++)
{
fscanf(ifp, "%d", &ipt);
queue_enqueue(data, ipt);
}
//creating a stack of queues
run_stack_t * runstack = run_stack_create();
queue_t * run = queue_create();
//finding runs and pushing them onto the stack
int runs = 0;
int *runpoint = &runs;
while(queue_is_empty(data) != 1)
{
run = extract_next_run(data);
run_stack_push(runstack, run);
*runpoint += 1;
optimizestack(runstack, runpoint);
}
//merging queues together in sorted order
data = run_stack_pop(runstack);
queue_t * merger;
runs -= 1;
for(int i=0; i<runs; i++)
{
merger = run_stack_pop(runstack);
data = merge(merger, data);
}
queue_destroy(merger);
//output
printqueue(data);
//freeing memory
queue_destroy(data);
//run_stack_destroy(runstack, runpoint);
free(runstack);
free(runpoint);
fclose(ifp);
}
and the zigzag.txt file that is read in is here:
10
9 8 7 6 8 4 2 3 2 1
I'm happy to try anything or include any other information that may be necessary, I'm just not sure how to solve this problem.
Thanks in advance!

Using wrapped Qt segfaults on Linux with only a basic example

I've been experimenting with wrapping some Qt classes with a C interface to use with my latest D project. For what ever reason, this code works fine on Windows but segfaults on Linux and I haven't been able to track down the reason behind it. I haven't tried building on OSX yet.
I'm using Qt 5.3, and running Linux Mint.
The code is kind of spread out over a few different files so I thought it might be easier if I put all the related code into some pastebins.
QApplication Wrapper Stuff
QMainWindow Wrapper Stuff
These are very thin wrappers though, so even if you don't look at them it should be easy enough to understand my test program.
#include <Application.h>
#include <MainWindow.h>
int main( int argc, char* argv[])
{
Qt_Application* app = Qt_Application_create(argc, argv);
Qt_MainWindow* window = Qt_MainWindow_create();
Qt_MainWindow_show(window);//<- Segfault happens here
Qt_Application_exec(app);
Qt_Application_destroy(app);
Qt_MainWindow_destroy(window);
return 0;
}
Due to some printf tests, I know the segfault happens on when I try to call Qt_MainWindow_show, and likewise I know the window object exists when I pass it so that isn't the cause. Also, if I comment Qt_MainWindow_show out, Qt_Application_exec will get called no problem so as far as I know the wrapped objects are being created correctly.
When I run gdb, it says:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff789a92a in strlen () from /lib/x86_64-linux-gnu/libc.so.6
getting the backtrace at the point of the segfault shows this:
#0 0x00007ffff789a92a in strlen () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff6b6c6bc in QCoreApplication::arguments() ()
from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Core.so.5
#2 0x00007ffff1470213 in ?? ()
from /home/jebbs/Qt/5.3/gcc_64/plugins/platforms/libqxcb.so
#3 0x00007ffff14705f9 in ?? ()
from /home/jebbs/Qt/5.3/gcc_64/plugins/platforms/libqxcb.so
#4 0x00007ffff147d127 in ?? ()
from /home/jebbs/Qt/5.3/gcc_64/plugins/platforms/libqxcb.so
#5 0x00007ffff1470009 in ?? ()
from /home/jebbs/Qt/5.3/gcc_64/plugins/platforms/libqxcb.so
#6 0x00007ffff5d47e03 in QWindow::create() ()
from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Gui.so.5
#7 0x00007ffff716b97a in QWidgetPrivate::create_sys(unsigned long long, bool, bool) () from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Widgets.so.5
#8 0x00007ffff714e6f5 in QWidget::create(unsigned long long, bool, bool) ()
from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Widgets.so.5
#9 0x00007ffff71512ea in QWidget::setVisible(bool) ()
from /home/jebbs/Qt/5.3/gcc_64/lib/libQt5Widgets.so.5
#10 0x00007ffff7bd8205 in Qt_MainWindow_show ()
from /home/jebbs/Documents/projects/HeliosCTest/libqtcl.so.1
#11 0x0000000000400922 in main (argc=1, argv=0x7fffffffe158) at main.cpp:22 <-actually points to Qt_MainWindow_show(window), but this is from a test with printf's in it
So it looks like some string somewhere is NULL and strlen cries? I couldn't find any reason that QMainWindow.show() might segfault. Any pointers into where I should look or what I should do next would be an excellent help.

C: Segmentation fault and maybe GDB is lying to me

Here is a C function that segfaults:
void compileShaders(OGL_STATE_T *state) {
// First testing to see if I can access object properly. Correctly outputs:
// nsHandle: 6
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
// Next testing if glCreateProgram() returns proper value. Correctly outputs:
// glCreateProgram: 1
printf("glCreateProgram: %d\n", glCreateProgram());
// Then the program segfaults on the following line according to gdb
state->nsHandle = glCreateProgram();
}
For the record state->nsHandle is of type GLuint and glCreateProgram() returns a GLuint so that shouldn't be my problem.
gdb says that my program segfaults on line 303 which is actually the comment line before that line. I don't know if that actually matters.
Is gdb lying to me? How do I debug this?
EDIT:
Turned off optimizations (-O3) and now it's working. If somebody could explain why that would be great though.
EDIT 2:
For the purpose of the comments, here's a watered down version of the important components:
typedef struct {
GLuint nsHandle;
} OGL_STATE_T;
int main (int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
compileShaders(state);
}
EDIT 3:
Here's a test I did:
int main(int argc, char *argv[]) {
OGL_STATE_T _state, *state=&_state;
// Assign value and try to print it in other function
state->nsHandle = 5;
compileShaders(state);
}
void compileShaders(OGL_STATE_T *state) {
// Test to see if the first call to state is getting optimized out
// Correctly outputs:
// nsHandle (At entry): 5
printf("nsHandle (At entry): %d\n", state->nsHandle);
}
Not sure if that helps anything or if the compiler would actually optimize the value from the main function.
EDIT 4:
Printed out pointer address in main and compileShaders and everything matches. So I'm gonna assume it's segfaulting somewhere else and gdb is lying to me about which line is actually causing it.
This is going to be guesswork based on what you have, but with optimization on this line:
state->nsHandle = 6;
printf("nsHandle: %d\n", state->nsHandle);
is probably optimized to just
printf("nsHandle: 6\n");
So the first access to state is where the segfault is. With optimization on GDB can report odd line numbers for where the issue is because the running code may no longer map cleanly to source code lines as you can see from the example above.
As mentioned in the comments, state is almost certainly not initialized. Some other difference in the optimized code is causing it to point to an invalid memory area whereas the non-optimized code it's pointing somewhere valid.
This might happen if you're doing something with pointers directly that prevents the optimizer from 'seeing' that a given variable is used.
A sanity check would be useful to check that state != 0 but it'll not help if it's non-zero but invalid.
You'd need to post the calling code for anyone to tell you more. However, you asked how to debug it -- I would print (or use GDB to view) the value of state when that function is entered, I imagine it will be vastly different in optimized and non-optimized versions. Then track back to the function call to work out why that's the case.
EDIT
You posted the calling code -- that should be fine. Are you getting warnings when compiling (turn all the warnings on with -Wall). In any case my advice about printing the value of state in different scenarios still stands.
(removed comment about adding & since you edited the question again)
When you optimize your program, there is no more 1:1 mapping between source lines and emmitted code.
Typically, the compiler will reorder the code to be more efficient for your CPU, or will inline function call, etc...
This code is wrong:
*state=_state
It should be:
*state=&_state
Well, you edited your post, so ignore the above fix.
Check for the NULL condition before de-referencing the pointer or reading it. If the values you pass are NULL or if the values stored are NULL then you will hit segfault without performing any checks.
FYI: GDB Can't Lie !
I ended up starting a new thread with more relevant information and somebody found the answer. New thread is here:
GCC: Segmentation fault and debugging program that only crashes when optimized

MIT-SHM bindings for OCaml

I’m trying to extend OCaml-Xlib with bindings for the MIT-SHM extension.
It’s the first time I’m trying to interface C with OCaml and I’ve never written anything in C, so I guess I’m doing something stupid somewhere.
I first added the XShmQueryExtension function. I added the following to the Xlib.ml file
external xShmQueryExtension: dpy:display -> bool = "ml_xShmQueryExtension"
the following to the wrap_xlib.c file
CAMLprim value
ml_xShmQueryExtension( value dpy )
{
int ans = XShmQueryExtension( Display_val(dpy) );
return Val_bool(ans);
}
I changed the Makefile to link with Xext, and it works: when I call the xShmQueryExtension function from OCaml I get true.
Now I’m trying to write a function creating a shared xImage, initializing the shared memory and attaching it to the X server. I added the following to the Xlib.ml file:
type xShmSegmentInfo
external xShmCreateImageAndAttach:
dpy:display -> visual:visual -> depth:int -> fmt:ximage_format
-> width:uint -> height:uint -> xShmSegmentInfo * xImage
= "ml_xShmCreateImageAndAttach_bytecode"
"ml_xShmCreateImageAndAttach"
and the following to the wrap_xlib.c file:
#define Val_XShmSegmentInfo(d) ((value)(d))
#define XShmSegmentInfo_val(v) ((XShmSegmentInfo *)(v))
CAMLprim value
ml_xShmCreateImageAndAttach( value dpy, value visual, value depth, value format,
value width, value height)
{
CAMLparam5(dpy, visual, depth, format, width);
CAMLxparam1(height);
CAMLlocal1(ret);
XShmSegmentInfo *shminfo = malloc(sizeof(XShmSegmentInfo));
XImage *ximage = XShmCreateImage(
Display_val(dpy),
Visual_val(visual),
Int_val(depth),
XImage_format_val(format),
NULL,
shminfo,
UInt_val(width),
UInt_val(height)
);
shminfo->shmid = shmget (IPC_PRIVATE,
ximage->bytes_per_line * ximage->height, IPC_CREAT|0777);
shminfo->shmaddr = ximage->data = (char *) shmat (shminfo->shmid, 0, 0);
if (shminfo->shmaddr == -1)
fprintf(stderr,"Error");
shminfo->readOnly = False;
XShmAttach (Display_val(dpy), shminfo);
ret = caml_alloc(2, 0);
Store_field(ret, 0, Val_XShmSegmentInfo(shminfo) );
Store_field(ret, 1, Val_XImage(ximage) );
CAMLreturn(ret);
}
CAMLprim value
ml_xShmCreateImageAndAttach_bytecode( value * argv, int argn )
{
return ml_xShmCreateImageAndAttach(argv[0], argv[1], argv[2], argv[3],
argv[4], argv[5]);
}
Now I’m calling this function in my OCaml program:
let disp = xOpenDisplay ""
let screen = xDefaultScreen disp
let (shminfo, image) = xShmCreateImageAndAttach disp
(xDefaultVisual disp screen)
(xDefaultDepth disp screen) ZPixmap 640 174
This is a toplevel call in my OCaml program, and I’m never using the variables shminfo and image again (this is just to test that the function work). This call does not fail, but my program segfault a little while after (the rest of my program constantly dump the screen with xGetImage and do stuff with the pixels, and I get a segfault in some xGetPixel which has nothing to do with the call to xShmCreateImageAndAttach above).
I noticed that if I remove the line shminfo->shmaddr = ximage->data = (char *) shmat (shminfo->shmid, 0, 0); I don’t get the segfault anymore (but of course this won’t do what I want).
I assume that this has to do with the garbage collector somehow but I don’t know how to fix it.
On the OCaml doc, there is a warning about casting pointers obtained with malloc to the value type, but I don’t really understand what it means and I don’t know if it’s relevant.
Edit:
I replaced the two lines following shmat by the following:
fprintf(stderr,"%i\n",(int)shminfo->shmaddr);
fflush(stderr);
and I get something like 1009700864, so the call to shmat seems to be working.
Here is the backtrace given by gdb:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7acdde8 in ?? () from /usr/lib/libX11.so.6
(gdb) backtrace
#0 0x00007ffff7acdde8 in ?? () from /usr/lib/libX11.so.6
#1 0x000000000044070c in ml_XGetPixel ()
#2 0x00000000004165b9 in camlInit__rvb_at_1023 () at init.ml:43
#3 0x0000000000415743 in camlParse__find_guy_1046 () at parse.ml:58
#4 0x000000000041610c in camlParse__pre_parse_1044 () at parse.ml:95
#5 0x0000000000415565 in camlGame__entry () at game.ml:26
#6 0x00000000004141f9 in caml_program ()
#7 0x000000000045c03e in caml_start_program ()
#8 0x000000000044afa5 in caml_main ()
#9 0x000000000044afe0 in main ()
The warning is relevant if X is going to call free() on the shminfo pointer that you're casting to the value type. The problem is that OCaml assumes that values can be freely copied and handled later by GC. This isn't true for your pointer value, so there will potentially be dangling copies of the pointer. Also, the space can get reused as part of OCaml's heap, and then you have real trouble.
It doesn't seem to me that X will do this, and since you don't call free() in your code, I don't think this is the problem. But it could be--I don't know how X works.
It might be good to call fflush(stderr) after your call to fprintf(). It probably won't change anything, but I've found my tracing messages tend to get buffered up and never appear when the program crashes.
It would also be good to know what the segfaulting address looks like. Is it near 0? Or a big address in the middle of the heap somewhere?
Sorry I can't pinpoint your error. I don't see anything you're doing wrong after 4 or 5 readings of the code, assuming Display_val and the rest are working correctly. But this is tricky to get right.

Why am I getting core dumped? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Please help me. I can't figure out why I get a core dumped when I run this program. Before returning anything I can print all_albums_p just fine. Why am I getting core dumped?
#include "music_server.h"
struct album_ {
int num_tracks;
char **tracks;
int **playlist_hits;
};
typedef struct album_ album;
album *parse_album(FILE *album_file,int *number_of_albums){
int number_of_album,number_of_tracks,number_of_charaters;
int i,j;
char dummy_space;
int *p;
fscanf(album_file,"%d", &number_of_album);
*number_of_albums = number_of_album;
album *all_albums_p = (album *)malloc(sizeof(album)*number_of_album);
for(j=0;j<number_of_album;j++){
fscanf(album_file,"%d", &all_albums_p[j].num_tracks);
all_albums_p[j].tracks = calloc(all_albums_p[j].num_tracks,sizeof(char));
all_albums_p[j].playlist_hits = calloc(all_albums_p[j].num_tracks,sizeof(int));
/*Line 27*/ for(i=0;i<all_albums_p[j].num_tracks;i++){
fscanf(album_file,"%d", &number_of_charaters);
all_albums_p[j].tracks[i] = (char *)calloc(number_of_charaters+1,sizeof(char));
all_albums_p[j].playlist_hits[i] = (int *)malloc(sizeof(int));
all_albums_p[j].playlist_hits[i] = 0;
fscanf(album_file," ",dummy_space);
fscanf(album_file, "%[^\n]s", all_albums_p[j].tracks[i]);
}
}
return all_albums_p;
}
main(int argc, char *argv[]){
int i,j;
int *number_of_albums,*number_of_tracks,a;
a=0;
number_of_albums = &a;
album *all_tracks_ptr;
album_file = fopen(argv[1],"r");
transaction_file = fopen(argv[2],"r");
if((album_file == NULL) || (transaction_file == NULL)){
printf("Either %s or %s could not be open");
}else{
all_tracks_ptr = parse_album(album_file,number_of_albums);
int number_of_tracks[*number_of_albums];
}
}
errors:
Bus Error (core dumped)
(gdb) bt
#0 0xff277c9c in _smalloc () from /lib/libc.so.1
#1 0xff277d10 in malloc () from /lib/libc.so.1
#2 0xff263830 in calloc () from /lib/libc.so.1
#3 0x00010dd8 in parse_album (album_file=0xff3675bc,
number_of_albums=0xffbff894) at functions.c:27
#4 0x00010b80 in main (argc=3, argv=0xffbff90c) at project3.c:19
You should allocate sizeof(char*) below instead of sizeof(char)
all_albums_p[j].tracks = alloc(all_albums_p[j].num_tracks,sizeof(char*));
Since that looks like a Unix message ("Bus Error (core dumped)) I will assume you are using some flavor of Unix.
So, compile your program with debugging info output turned on and with optimization turned off. If you're using gcc or something gcc-compatible, that would be the -g -O0 command line options.
Then run your program and have it crash. Locate the core dump (I'll call it corefile in this example) and then type:
gdb programname corefile
Then when you get the gdb prompt, type bt (for backtrace) to see the program's stackframe. That will tell you where the program crashed and you can examine that part of your program more closely.
Update:
I think your problem is here:
all_albums_p[j].tracks = calloc(all_albums_p[j].num_tracks,sizeof(char));
album.tracks is defined as char**. However, what you're assigning to all_albums_p[j].tracks is a block of memory the size of num_tracks char. You need to assign to it a block of memory big enough to hold num_tracks char *. So you probably need to change the line to:
all_albums_p[j].tracks = (char **) calloc(all_albums_p[j].num_tracks,sizeof(char *));
Use a debugger or valgrind and figure out what line the problem is occurring on. Then you will know what part of your code is bad.

Resources