The function _gx_system_timer_expiration() calls _gx_system_event_fold(&timer_event) without setting all of the elements of the timer_event structure.
This causes timer_event.gx_event_target to have a random value – whatever happened to be on the stack since timer_event is an automatic variable.
This causes the system to crash sporadically.
If the code calls _gx_widget_delete(), it calls _gx_system_event_remove().
In the middle of _gx_system_event_remove(), there is the following code:
if (pEvent->gx_event_target)
{
if (pEvent->gx_event_target == widget)
{
Purge = GX_TRUE;
}
else
{
_gx_widget_child_detect(widget, pEvent->gx_event_target, &Purge);
}
if (Purge)
{
pEvent->gx_event_target = GX_NULL;
pEvent->gx_event_type = 0;
}
}
Since timer_event.gx_event_target was filled with garbage in _gx_system_timer_expiration(), the NULL check for pEvent->gx_event_target passes whereas it should have failed if timer_event.gx_event_target had been set to GX_NULL in _gx_system_timer_expiration().
The test for a match with widget invariably fails and _gx_widget_child_detect() is called.
_gx_widget_child_detect() goes through a linked list starting with a garbage pointer and eventually causes a Fault (I think it was a Bus Fault).
The fix to this problem is to modify gx_system_timer_expiration.c shown below in yellow highlighter:
void _gx_system_timer_expiration(ULONG val)
{
GX_EVENT timer_event;
GX_PARAMETER_NOT_USED(val);
/* if there are no active timers just stop the timer from running */
if (_gx_system_active_timer_list == GX_NULL &&
_gx_system_animation_list == GX_NULL)
{
#ifdef GX_THREADX_BINDING
_tx_timer_deactivate(&_gx_system_timer);
#else
GX_TIMER_STOP;
#endif
return;
}
timer_event.gx_event_type = GX_EVENT_TIMER; /* was hard-coded as 11 */
timer_event.gx_event_display_handle = 0; /* is this necessary? */
timer_event.gx_event_target = GX_NULL; /* send event to the widget that has the focus */
timer_event.gx_event_sender = 0;
timer_event.gx_event_payload.gx_event_ulongdata = 1;
_gx_system_event_fold(&timer_event);
}
This problem took a great deal of time to debug.
I’m surprised Express Logic didn’t find this bug when they ran their static code analyzer on the code.