Help error search crash in my raycasting 3D game

Hi All,

Im working on a sort of "Wolfenstein 3D" clone for the Playdate. At this point, it does raycasting that allows you to traverse a simple 3D level. I'm bit worried about the performance however and would like to know how it runs on a physical device (still waiting for mine).

This is what it looks like from the simulator:
http://jimmiejohnsson84.me/imgs/game3DTest.gif

Originally, I wanted to get some feedback on performance on it but it turns out it hard crashes on the device so now I'm instead trying to find out why it crashes on the device.
A (very) verbose version can be found here:

From what I've understood, if you connect the playdate device to the computer and run it you should be able to see the logs that it outputs before it crashes.

If you feel like helping out and trying to hunt down the crash I'd be very grateful ofc.

Cheers,
/Jimmie

Hey Jimmie.
I'm afraid this isn't working for me. It doesn't load into the simulator for me, giving me the following error:


And if I try to sideload it to the PD the console crashes after running it.

1 Like

Hi Alex,

Thanks for giving it a try!

I've only uploaded a build for the physical device as I really am mostly interested in how it runs on a real device. It runs fine in the simulator but that might not translate well to performance on the device.

I've got confirmation that it crashes on the device :frowning:
I did have created another build that tries to limit it down and only draws the wall - its sitting at

If you feel like trying it out and helping out finding the bug than I ofc would be very grateful :slight_smile: I unfortunately dont have a device myself and the crash only happens on a physical device - not in the simulator.

That's not updaing on the device for me - make sure you're incrementing the buildNumber field in the pdxinfo for each build you do or it won't update.

Probably worth incrementing the version number too. I can't remember which one is more important offhand, I just put the build number on the end of the version number these days.

Ok, I removed the game from my PD account and sideloaded the second zip and reinstalled it on the device, to guarantee it was the latest build. It still crashes, I'm afraid. There's no output to the console, so if you're printing anything to that then the crash is occurring before that.

1 Like

Thanks for helping out! Yeah seems to happen before.

Ill try and post another build with even less happening and more logging.

Again, thanks for taking the time! Appreciate it :slight_smile:

Hi Alex,

I've uploaded a very verbose version that should spew out a lot to the log.
Its sitting here TestPD3_FindCrashv1.zip - Google Drive

From what I remember reading in another post about crashes you should be able to see the logToConsole messages if you have the cable connected (and run something on your pc) while loading the game on the device.

If you feel like giving it a go and reporting back the log messages I would ofc be super grateful but I also 100% understand if you dont wanna spend more time on it :slight_smile:

/Jimmie

Here's the log! Looks like it gets done with the first frame and crashes before it can swap the buffer maybe

setupGame started
CreateBackBuffer called
g_backBuffer 0x60004190
g_backBufferBitmapRowbytes 52, g_backBufferData 0x600041a0
g_backBufferRGB 0x60007270 size: 288000
ClearBackBuffer called, g_backBufferRGB : 0x60007270
ClearBackBuffer cleared mem
CreateZBuffer called
g_ZBuffer 0x6004d780
Loading images
bmp stats 54 12288 64 64
Loaded wall.bmp at 0x6004ddd0
bmp stats 54 12288 64 64
Loaded floor.bmp at 0x60050de0
bmp stats 54 12288 64 64
Loaded ceiling at 0x60053df0
bmp stats 54 12288 64 64
Loaded sprite at 0x60056e00
setupGame finished
renderWalls called
x : 0
...
x : 399
renderWalls finished
1 Like

Thanks for testing it!

It renders a 2D image in full RGB that it later on performs a dithering on, I would have expected to see a "makeDitherFS called" in the log before it crashed if it managed to get to the "renderWalls finished" section...
My guess is still that either the dithering or conversion from the dithered image to the playdates buffer caused it to crash.

I can post a build that just cuts out the dithering and swapping to the playdates buffer and see if the crash goes away.

Again, thanks a million for testing it out!

I can't tell much from running it on the hardware debugger, but it does look like a stack overflow. When the fault handler is triggered the process stack pointer is 374,024 bytes below the bottom of the game task stack. :flushed: Memory is pretty tight on Playdate--we've only got a 10 KB stack there. Does stack overflow sound like a likely cause?

If there's anything else you'd like me to test, just let me know!

1 Like

Thanks a million for taking the time help out!

I'm trying to narrow it down further, so I've got 5 separate versions uploaded that tries to rule out different sections of the code that could cause the crash. I've tested them all in the simulator and they all run fine with no crashes (as is expected), hopefully one or more of them will run on the device as well without crashing and help me narrow down where the actual issue may be.

They all produce a lot of loggings using logToConsole.

rayCasterCrashv2_no_dithering.pdx.zip (rayCasterCrashv2_no_dithering.pdx.zip - Google Drive)

  • Renders walls, dose'nt perform dithering, draws to playdate back buffer and finally calls pd->graphics->drawBitmap to display rendered image.
    If it runs, you should se something.

rayCasterCrashv3_nodit_noupdbuff.zip (rayCasterCrashv3_nodit_noupdbuff.zip - Google Drive)

  • Renders walls, dose'nt perform dithering, dosent draw to playdate back buffer, calls pd->graphics->drawBitmap to display rendered image.
    Dont think this one displays anything.

rayCasterCrashv4_onlyDrwWalls.zip (rayCasterCrashv4_onlyDrwWalls.zip - Google Drive)

  • Renders walls, dose'nt perform dithering, dosent draw to playdate back buffer, no call to pd->graphics->drawBitmap.
    Dose'nt display anything.

rayCasterCrashv5_nowalls_justOther.zip (rayCasterCrashv5_nowalls_justOther.zip - Google Drive)

  • Dose'nt renders walls, performs dithering, draws to playdate back buffer and finally call to pd->graphics->drawBitmap.
    Might show a black screen, but dose'nt display anything interesting.

rayCasterCrashv6_nodit_flat.zip (rayCasterCrashv6_nodit_flat.zip - Google Drive)

  • Renders walls without textures, dose'nt perform dithering, draws to playdate back buffer and finally calls pd->graphics->drawBitmap to display rendered image.
    If it runs, you should se something.

I've bumped the version nr on all of them so it should out update if you load them in (they are in range from 1.2 - 1.6, my previous version was 1.1)

All and any testing of this is greatly appreciated ofc!

Hi Dave,

First of all - thanks for helping out, greatly appreciate it!
The game dose'nt use a lot stack allocated memory so I cant really see that this should be a problem - but I will read through the code again and try and see if there is something Im missing. It dose'nt use recursion at all so should'nt be the problem either.

This is what the memory allocations look like from within the simulator. I'm not sure if this shows only memory on the heap or on the stack as well? This is not from any of the "crash search" versions I've posted here but rather the running version.

I posted a reply further down with a couple of new versions that each try and rule out some section of the code by simply not running it and see if I can narrow down the issue that way. If you got the time and energy to try them out then ofc it would be greatly appreciated!

Thanks again,
/Jimmie

Hi Alex,

Posted a new set of builds in a reply further down. If you got the time and energy to test them out it would ofc be greatly appreciated :slight_smile:

Anyways, thanks a million for your help!

/Jimmie

1 Like

All run as described, except for v5 which crashes in the same way as before, last thing on the console log there is setupGame finished. Looks like the dither code is the culprit. Do you want any of the other log messages?

About stack allocations, no they won't show up in the malloc log. I can't think of any good way to track those, unfortunately. I dumped a disassembly of the pdex.bin in v5 and searched for usage of the sp stack pointer register, don't see anything that's obviously pushing it way out of bounds.. Ah! Okay, I poked around some more and got lucky. At 0x600024c8 it's moving the stack pointer down with

    sub.w	sp, sp, r3

and $r3 is 384,000 there. You can see what line that is with

    arm-none-eabi-addr2line -e <path to pdex.elf> 0x600024c8

How I did it: I set a breakpoint at the logToConsole function to see if there were any calls that weren't making it out to the serial port before crashing, found one that mentioned a large allocation, set a breakpoint in the calling function at the next branch instruction, and found the stack pointer was way out of bounds at that point. Scanned the code between those two points, and quickly spotted the culprit. Ran again with a breakpoint there and confirmed that $r3 a huge value. I suspect you're doing something like

    float buffer[400*240];

inside a function, which puts that on the stack. If you're never recursing back into that function you can declare the array static and it'll move the allocation from the stack to a static memory allocation. And not crash. :slight_smile:

2 Likes

Wow, solid work mate! Thanks!!

Now that I look at the dithering code yeah it does seem like a stack overflow due to almost exactly what you wrote here:

int error[400*240].
I dont know how I missed it before... Sorry about that.

The dithering is a floyd bernstein that accumulates colors being rounded off for each pixel to determine which ones should be white or black.

That must be it.

I'll try and make a build that puts this on the heap and see if it stops crashing and perhaps we can see some actual performance figures instead :slight_smile:

1 Like

Ok, here is a version that hopefully does all the rendering of the walls and dose'nt crash - the dithering code now uses the heap (before it used the stack which most likely caused a stack overflow since it asks for 400*240 integers on the stack). I've bumped the version to 1.7 so should update fine.

You should be able to move around in the little mini level that is here. I've removed the very verbose logging in this one so it should perform not too different from my "working code".
If it does, I would be very happy to hear how it performs on a physical device. It is doing quite a lot of stuff so I would'nt be surprised if it runs slowly though :frowning:

Big, big thanks for helping out!

/Jjimmie

Thanks again a million!

I uploaded another build that address exactly this. It does feel very likely that this is the problem.

Yeeaaahhh dude it works! Nice one!!!
You got some optimisation to do though.

Think it's about 3fps?

1 Like

Very cool :smiley:
Yeah I was kind of afraid it would be slow, but yeah that is ridicolusly slow :joy:
I got hopes on getting a physical device from ebay soon, gonna try and see if I can squeeze out some proper performance with that.

Thanks to both of you for helping me hunt down the crash! Really appreciate it!