A small thing I ran into last week was having too much stuff in the data segment of the generated binary of a C based game. This came from a few too many global variables. This is easy enough to work around, but it would be good to have a check in the toolchain, as the corresponding crash is pretty hard to understand, and I was just lucky enough to guess the problem relatively early in the debugging process.
Edit: I forgot to note, this crash only happens on device, not on simulator, making it particularly troublesome.
How much memory were you using?
I wonder if the compiler can tell you.
I'm worried now. I dont have hardware yet, maybe my game is doomed...
This isn't about runtime heap or stack memory usage, this "data" is about the set of memory locations set in the layout of a binary itself (see picture); you have data for globals, rodata for string literals, text for code and other stuff I've forgotten about since OS class.
I can try to estimate the size of the data segment later (again, not runtime memory usage), but the stuff generated by the playdate toolchain doesnt seem to play nice with tools I would use to check it out like
This seems to work OK:
unix> size -A -d MyGame.pdx/pdex.so | grep -E 'text|data'
.text 44568 18432
.rodata 5039 65536
.data 2104 82464
But I'd still like to know if I now need to re-factor all the static data to be dynamically allocated (loaded from file on start-up, for example).
With the full output being:
section size addr
.note.gnu.property 32 680
.note.gnu.build-id 36 712
.gnu.hash 1252 752
.dynsym 3936 2008
.dynstr 2801 5944
.gnu.version 328 8746
.gnu.version_r 64 9080
.rela.dyn 2088 9144
.rela.plt 1488 11232
.init 27 16384
.plt 1008 16416
.plt.got 16 17424
.plt.sec 992 17440
.text 44568 18432
.fini 13 63000
.rodata 5039 65536
.eh_frame_hdr 844 70576
.eh_frame 3400 71424
.init_array 8 80768
.fini_array 8 80776
.dynamic 464 80784
.got 672 81248
.got.plt 520 81920
.data 2104 82464
.bss 179088 84576
.comment 43 0
.debug_aranges 288 0
.debug_info 99861 0
.debug_abbrev 3996 0
.debug_line 12874 0
.debug_str 16467 0
.debug_line_str 948 0
.debug_rnglists 45 0
This is almost never the case, but I don't have a linux box on me (size behaves differently on osx), but that tip is helpful ty @UrlOfSandwich !
One note, I could be wrong but I believe the .so/.dylib/.dll correspond to the simulator build, whereas the .bin corresponds to the device build (source: Inside Playdate with C) so we would need to check that file for the layout (please correct me if I'm misunderstanding!)
Ah, good to know.
So we need to run the arm cross-compiler tools on the
I found some information about getting
gcc to log some of this stuff, but was sidetracked before I could work out if any of it was useful.
I guess the
data segment size should be roughly the same between native & arm, unless your data structure layouts are packed really bad. (Back in the olden days, you'd get runtime packing-faults on arm)
EDIT: Hmm, my
pdex.bin is empty.
You need to do a separate build step for a device build, your config is probably just building simulator.
About the size difference, it could actually be quite drastic, outside of padding, one example is things like
size_t which will have different widths based on the platform they are targeting, 64 bits on the simulator, and 32 on the device.
I'm using a CMakeFile.txt I pinched from one of the example C-API projects in the SDK.
It doesn't seem to have any of those
make all works though (for a simulator OK, but 0-byte .bin build).
I will have a dig around other example cmake files and see if there's anything useful.
EDIT: Looking at the SDK CMake Files, it looks like you need to define TOOLCHAIN to be armgcc, e.g.:
cmake . -DTOOLCHAIN=armgcc -DCMAKE_BUILD_TYPE=Debug
This still doesn't define those targets, but at least it looks to be building an Arm version. All that said, it doesn't work:
[ 12%] Building C object CMakeFiles/Turret_DEVICE.dir/home/sando/Code/Play.Date /PlaydateSDK/PlaydateSDK-1.12.3/C_API/buildsupport/setup.c.o
/usr/bin/cc -DTARGET_EXTENSION=1 -DTARGET_PLAYDATE=1 -I/home/sando/Code/Play.Date/PlaydateSDK/PlaydateSDK-1.12.3/C_API -g -fdata-sections -Wall -Wno-unknown-pragmas -Wdouble-promotion -O2 -mthumb -mcpu=cortex-m7 -mfloat-abi=hard -mfpu=fpv5-sp-d16 -D__FPU_USED=1 -falign-functions=16 -fomit-frame-pointer -gdwarf-2 -fverbose-asm -ffunction-sections -fdata-sections -std=gnu11 -MD -MT CMakeFiles/Turret_DEVICE.dir/home/sando/Code/Play.Date/PlaydateSDK/PlaydateSDK-1.12.3/C_API/buildsupport/setup.c.o -MF CMakeFiles/Turret_DEVICE.dir/home/sando/Code/Play.Date/PlaydateSDK/PlaydateSDK-1.12.3/C_API/buildsupport/setup.c.o.d -o CMakeFiles/Turret_DEVICE.dir/home/sando/Code/Play.Date/PlaydateSDK/PlaydateSDK-1.12.3/C_API/buildsupport/setup.c.o -c /home/sando/Code/Play.Date/PlaydateSDK/PlaydateSDK-1.12.3/C_API/buildsupport/setup.c
cc: warning: ‘-mcpu=’ is deprecated; use ‘-mtune=’ or ‘-march=’ instead
cc: error: unrecognized command-line option ‘-mthumb’
cc: error: unrecognized command-line option ‘-mfloat-abi=hard’
cc: error: unrecognized command-line option ‘-mfpu=fpv5-sp-d16’
So the cmake include files, or my compiler is out of date.
-march do I give it?
I can share my build file, if that helps, but this is pulling a bit off topic from the purpose of the thread so further discussion should probably open a separate issue.
rm -r device_build/CMakeFiles/ device_build/CMakeCache.txt
rm -r sim_build/CMakeFiles/ sim_build/CMakeCache.txt
if [ ! -d "<insert-pdx-name>.pdx" ]; then
cmake -DCMAKE_BUILD_TYPE=Release ..
cmake -DCMAKE_TOOLCHAIN_FILE=<insert-relevant-path>/PlaydateSDK/C_API/buildsupport/arm.cmake -DCMAKE_BUILD_TYPE=Release ..
rm -r ../<insert-pdx-name>.pdx/ && make clean && make
rm -r ../<insert-pdx-name>.pdx && make clean && make
Note: I'm not saying the above script is good, its probably terrible, but it got the build working and I just am too old to mess with build files any more
I, um, ... don't have the arm development environment installed on this machine.
I'll get that fixed ASAP.