PDA

View Full Version : Tracking segfaults



Darkhog
24-06-2013, 01:32 AM
While fighting with chunk rendering, I've encountered problem which is segfault. Problem is that debugger points me to fpc_popaddrstack symbol, which is too vague to be of any use. How can I track it more precisely (note that I know most likely culprit, but those are three function chained from one and I need to know where it really occurs).

//edit: It seems to be worse than I thought, it seems to be multiple segfaults from different sources - after I seem to fix one, another pops up, but with same symbol.

If anyone is willing to help me debugging it, I can send compressed project folder. Dunno if I can debug it on my own.

laggyluk
24-06-2013, 03:14 AM
you've checked the 'call stack' window? it helps tracking crash history

Darkhog
24-06-2013, 08:21 AM
Yeah, it looks like this:

#0 fpc_popaddrstack at :0
#1 ?? at :0
#2 TSPRITE__CREATE(0x1848720, 0x1846a58, 0x42a428, <error reading variable>) at sprites.pas:39
#3 TTILESET__GETTILESPRITE(4, <error reading variable>) at tilesets.pas:65
#4 TCHUNK__GETTERRAINSPRITE(0x158d170, <error reading variable>) at chunkutils.pas:264
#5 TCHUNK__DRAW(0x1846d20, 0, 64, 0x158d170, 4, true, <error reading variable>) at chunkutils.pas:177
#6 DRAW at alletest.lpr:37
#7 main at alletest.lpr:158

But dunno how to interpret this.

paul_nicholls
24-06-2013, 08:31 AM
If anyone is willing to help me debugging it, I can send compressed project folder. Dunno if I can debug it on my own.

I could give debugging it a try if you want...I have Lazarus 1.0 installed on my windows 8 laptop here - just PM me :)

Darkhog
24-06-2013, 08:53 AM
OK. Do you have allegro.pas installed as well? You'll need it to compile this (and possibly you'll have to adjust directories in project options).

paul_nicholls
24-06-2013, 10:23 AM
I have now installed allegro.pas and gotten it to compile. It crashes after generating a few new chunks.

laggyluk
24-06-2013, 10:52 AM
Yeah, it looks like this:

#0 fpc_popaddrstack at :0
#1 ?? at :0
#2 TSPRITE__CREATE(0x1848720, 0x1846a58, 0x42a428, <error reading variable>) at sprites.pas:39
#3 TTILESET__GETTILESPRITE(4, <error reading variable>) at tilesets.pas:65
#4 TCHUNK__GETTERRAINSPRITE(0x158d170, <error reading variable>) at chunkutils.pas:264
#5 TCHUNK__DRAW(0x1846d20, 0, 64, 0x158d170, 4, true, <error reading variable>) at chunkutils.pas:177
#6 DRAW at alletest.lpr:37
#7 main at alletest.lpr:158

But dunno how to interpret this.
those are procedures/functions that were called prior to crash.
on top is most recent one and going down you can track what have led there. btw why you create sprite after chunk.draw? shouldn't it be done in some init part?

Darkhog
24-06-2013, 11:28 AM
Sprite is created IN Tchunk.draw. This is because how they are handled in game - they are created as necessary and destroyed when no longer needed. Because of that memory used by game is about 30... MB and it should in theory run even on old 128mb machines.

laggyluk
24-06-2013, 11:59 AM
well ok i guess as long as you are not loading resources there. anyways looks like problem lies around* tsprite.create

Darkhog
24-06-2013, 02:06 PM
I can send you sources, if you want to look into it.

imcold
24-06-2013, 03:34 PM
I can give it a try, too.

laggyluk
24-06-2013, 03:42 PM
I can send you sources, if you want to look into it.
ok i can give it a shot

Darkhog
24-06-2013, 04:07 PM
Pm'ed Laggyluk, will PM imcold in a minute.

//edit: PM'ed imcold as well.

SilverWarior
24-06-2013, 06:36 PM
Can you send it to me also. I would also like to try help you out.
And besides since I'm closely folowing Factorio which also uses allegro game engine it would probably give me better idea of what it is posible to do with allegro and what not. This way I could probably give better suggestion to Factorio developers. And no Factorio is unfortunately not made with pascal.

imcold
24-06-2013, 07:35 PM
You're getting errors due to changing the Chunk.Data in your keyboard handling code. The your keyboard handler is running in another context/thread (read the doc carefully: http://allegro-pas.sourceforge.net/docs/allegro.html#al_install_int_ex). What does this mean? The data modified in the handler can change at any moment, independently of your main loop routine - if it changes when you're in your Draw routine, all hell's gonna break loose due to invalid pointers etc.
The solution is to just set a flag to signal that a world refresh is needed, and check it in the main loop (and there should be a lock around the flag, to do things 100% properly; but you can probably get away without it in this case).


var
update_chunks: boolean;

procedure RegenerateChunk;
begin
update_chunks := false;
Chunk.Data:=WorldGenerator.GenerateChunkData(chunk x,0,18);
Inc(chunkx);
al_clear_to_color(perlin,al_makecol(255,0,255));
for x:=0 to 100-1 do
begin
for y:=0 to 100-1 do
begin
al_putpixel(perlin,x,y,generate_pixel(x,y));
end;
end;
end;

procedure update_keyboard();
begin
Dec(lasted);
dec(chunklasted);
if (al_keyboard_needs_poll) then al_poll_keyboard;
if ((al_key[AL_KEY_P]<>0) and (lasted<=0)) then begin pause:=not pause; lasted:=pausedelay; end;
if not pause then begin

if ((al_key[AL_KEY_SPACE]<>0) and (chunklasted<=0)) then
begin
update_chunks := true;
chunklasted:=pausedelay;
end;
end;
end;


main routine:

repeat
draw;
if update_chunks then
RegenerateChunk;
until (al_key[AL_KEY_Q]<>0) or quit;

Darkhog
25-06-2013, 06:58 AM
imcold that fixed it, I think. Thank you!

Ñuño Martínez
27-06-2013, 10:02 AM
Hi. I know I'm late but ...

imcold that fixed it, I think. Thank you!
Does it means that the code you send me by PM was fixed?

Anyway, the way you made the main loop and the keyboard handler aren't recommendable. You shouldn't manage the user input in an interruption (as documentation says it's called in "interruption time" not in "execution time"). I recommend you to read the timers tutorial (http://allegro-pas.sourceforge.net/wiki/doku.php?id=tutorials:timers) and the sources of the Allegro.pas' demo game.

Darkhog
27-06-2013, 10:42 AM
Well, when I've tried it in mainloop it ran too fast. Plus I only need keyboard to be read 60 frames per second, all over this would be excessive.

Ñuño Martínez
03-07-2013, 11:21 AM
Well, you can set the speed or your "logic loop", even use two counters. I don't see the problem.

phibermon
03-07-2013, 03:45 PM
The rate of any spinning threads and/or polling you need to do should all be configurable. As a general rule of thumb you should avoid maxing a bunch of threads out as it leads to more unpredictable switches between threads by the OS Scheduler (IE what if you don't return to the audio thread quickly enough to keep the output buffer filled etc) You want things as fast as they'll go whilst retaining a consistent execution rate.