While working on my Pebble watchface “Future Time” I have encountered persistent annoying problem – watchface would run for a while and then crash – and not only crash, but actually restart the watch. What made this even more frustrating – after 3 restarts in a row Pebble would revert to recovery mode and complete firmware reinstall was required (did I accidentally write a Pebble virus?).
When I dug into device logs I found out that every restart was given reason: “Dangerous Stack Overflow”. Which is kinda strange – I don’t have any recursions nor deeply nested function calls nor large local variables. I tried lots of things – including extreme ones like declaring all local function variables as global or static – nothing helped.
Finally Christian form Pebble developers forum shed a light. He pointed out that I use a lot of GRect constructs which is basic rectangle building block for pretty much anything from defining layers to graphics functions. I used GRect inline directly inside function calls, which I thought wasn’t a big deal, after all “everybody does that” – including Pebble in its examples. Well, as Christian pointed out those GRects are kind of local variables, and either memory is not reclaimed fast enough when they go out of scope or they spring memory leak.
Keeping this in mind I created a global GRect variable and when needed to use a GRect in local function, first I’d assign it’s value to the variable and then use variable in the function.
So something like this:
static void layer_update(Layer *layer, GContext *ctx) { //... graphics_draw_rect(ctx, GRect(10, 10, 30, 30)); //... graphics_draw_bitmap_in_rect(ctx, bitmap, GRect(20, 20, 40, 40)); }
Becomes thus:
GRect temp_rect; static void layer_update(Layer *layer, GContext *ctx) { //... temp_rect = GRect(10, 10, 30, 30); graphics_draw_rect(ctx, temp_rect); //... temp_rect = GRect(20, 20, 40, 40); graphics_draw_bitmap_in_rect(ctx, bitmap, temp_rect); }
That’s it. This simple change cured the plague, no more crashes, restarts or recovery – just smooth sailing.