C API random crashes on device

,

Hi everyone,

I'm experimenting with a sparse set-based ECS pattern in C for the Playdate. In the Simulator, everything works fine, but the device itself crashes. The crashes don't always happen in the same place, and sometimes the app runs without crashing at all.

Crashlog looks like this:

build:57176cb0-2.6.2-release.177516-buildbot
   r0:90000700    r1:0000005c     r2:0000005c    r3: 900005d0
  r12:0000000a    lr:90000173     pc:9000032a   psr: a1070000
 cfsr:00000082  hfsr:00000000  mmfar:d00023c0  bfar: d00023c0
rcccsr:00000000
heap allocated: 3008
Lua totalbytes=0 GCdebt=0 GCestimate=0 stacksize=0

Project code with reproduction setup you can find here

I’d appreciate any suggestions or insights into what might be causing this issue.

That's a segfault if I've ever seen one. You can try running arm-none-eabi-addr2line to determine where in your C code this is happening -- though the address should be 0x0000032a.

Building it myself, it appears your error is somewhere in SparseSetCreate. Taking a quick look at the code, though, I don't see what could be going wrong.

Additional crash logs would be helpful, since you said it doesn't crash in the same place each time.

You are right! The problem was that after allocating sparse and dense arrays, I wasn’t clearing the data inside, which caused a crash when reading from them. Using addr2line was excellent advice—thank you so much! :smile:

One thing still puzzles me, though: the pc in the crash log is 9000032a. How did you come up with 0x0000032a?

The Playdate device uses two different start addresses depending on revision -- the first batch of Playdates (up to and including some of pre-order Group Four) have a different memory map, so application code starts at 0x60000000 on those devices.
Due to this difference, Panic reworked the pdex.bin executable format for both sets of devices when Playdate OS v2.0.0 was in development, alongside the newer Playdate revision. One of the side effects of this was that the linking process uses a relocatable file instead of strictly static linking because of the different memory maps, compiling the start of the ELF's .text segment to address 0x00000000.
The binary is then read by the device binary loader and copied to the correct address in RAM (for the newer devices it's 0x90000000, and the older ones have a start address of 0x60000000).