Crash calling setImage multiple times in C when Lua environment is initialized

,

When setting up benchmarks for Nim and Lua, @Nino found that calling setImage many times with no pauses from Nim (the same from C) crashed both the simulator and device.

Later we discovered that the crash only happens when the Lua environment has been initialized.
That means, the native C/Nim update callback is set during the kEventInitLua.

This is the crash log I got on macOS:

Thread 0 Crashed::  Dispatch queue: com.apple.main-thread
0   libsystem_kernel.dylib        	       0x19057d11c __pthread_kill + 8
1   libsystem_pthread.dylib       	       0x1905b4cc0 pthread_kill + 288
2   libsystem_c.dylib             	       0x1904c4a40 abort + 180
3   Playdate Simulator            	       0x104aa44c8 luaD_throw + 84
4   Playdate Simulator            	       0x104ad18a0 luaG_errormsg + 168
5   Playdate Simulator            	       0x104ab55a0 lua_error + 160
6   Playdate Simulator            	       0x104a9de4c luaL_error + 76
7   Playdate Simulator            	       0x104afaf0c pc_luaError + 80
8   Playdate Simulator            	       0x104ab350c auxgetstr + 224
9   Playdate Simulator            	       0x104a9e368 luaL_testudata + 76
10  Playdate Simulator            	       0x104a9e3c8 luaL_checkudata + 32
11  Playdate Simulator            	       0x104af65b0 luasprite_setImage + 108
12  Playdate Simulator            	       0x104af6508 pc_sprite_setImage + 140
13  pdex.dylib                    	       0x10c976de8 setImage__OOZOOZOOZOOZOnimbleZpkgsZplaydate4548O4949O50ZplaydateZsprite_781 + 208 (sprite.nim:120)
14  pdex.dylib                    	       0x10c97d510 colonanonymous___bench_225 + 104 (bench.nim:124)
15  pdex.dylib                    	       0x10c97ee54 update__bench_550 + 1368 (bench.nim:242)
16  pdex.dylib                    	       0x10c984050 update__screen_9 + 392 (screen.nim:6)
17  pdex.dylib                    	       0x10c98379c catchingUpdate__nim95snake_10 + 368 (nim_snake.nim:19)
18  pdex.dylib                    	       0x10c97303c privateUpdate__OOZOOZOOZOOZOnimbleZpkgsZplaydate4548O4949O50ZplaydateZsystem_75 + 312 (system.nim:38)
19  Playdate Simulator            	       0x104b03064 pd_update + 468
20  Playdate Simulator            	       0x104b55850 -[PCPlaydateSimulator update] + 508
21  Foundation                    	       0x1917b62d8 __NSThreadPerformPerform + 264
22  CoreFoundation                	       0x190691cfc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28
23  CoreFoundation                	       0x190691c90 __CFRunLoopDoSource0 + 176
24  CoreFoundation                	       0x190691a00 __CFRunLoopDoSources0 + 244
25  CoreFoundation                	       0x1906905f0 __CFRunLoopRun + 828
26  CoreFoundation                	       0x19068fc5c CFRunLoopRunSpecific + 608
27  HIToolbox                     	       0x19ac0c448 RunCurrentEventLoopInMode + 292
28  HIToolbox                     	       0x19ac0c0d8 ReceiveNextEventCommon + 220
29  HIToolbox                     	       0x19ac0bfdc _BlockUntilNextEventMatchingListInModeWithFilter + 76
30  AppKit                        	       0x193e6ac54 _DPSNextEvent + 660
31  AppKit                        	       0x194640ebc -[NSApplication(NSEventRouting) _nextEventMatchingEventMask:untilDate:inMode:dequeue:] + 716
32  AppKit                        	       0x193e5e100 -[NSApplication run] + 476
33  AppKit                        	       0x193e353cc NSApplicationMain + 880
34  dyld                          	       0x1902390e0 start + 2360

Having Lua enabled, seems like a C call to setImage goes through quite a few Lua related stuff under the hood, and in our scenario it causes a crash.

Here's a minimal reproduction project in C:
c-sprite-game.zip (8.8 KB)

In this project, calling setImage more than 15 times in the for loop in main.c crashes the simulator.
Here's also the GitHub issue of the report: LCD:Sprite.setImage crashes when invoked multiple times · Issue #27 · samdze/playdate-nim · GitHub

2 Likes

Got it: The C->lua setImage() bridge was leaving a value on the stack. Do that too many times and the Lua stack explodes. Thanks for catching this! I'll get the fix in now and schedule it for 2.4.

1 Like