Programming => General => Topic started by: rborsey on October 06, 2019, 08:51:05 pm

Title: GDB Exception raised on Autosize
Post by: rborsey on October 06, 2019, 08:51:05 pm
I am creating a (relatively) large application and have recurring but intermittent crashes. In the IDE it reports an error in Laztrace which on inspection is an explicitly raised GDBException. The call stack (.png attached) reveals that the exception is being raised in TWinControl.DoAllAutosize line 3547 because cfAutoSizeNeeded is in fControlFlags. The stack reveals that it all starts with a simple TLabel caption update. The TLabel is in a TScrollBox which is one of several at the top level on the main form - I use the scroll boxes as effectively different screens in the application, making one visible at a time. The label, the scrollbox and the main form all have autosize false (ie not autosize). The label is updated once per second (it displays the remaining time of an audio file play) and the exception typically happens after a minute or two of updates so is to some extent non-deterministic.

Is there anybody who understands what is happening please.

Cheers from a rainy France
Title: Re: GDB Exception raised on Autosize
Post by: jamie on October 06, 2019, 09:42:44 pm
Can't say without actually seeing some code but I am going out on the limb is saying that maybe your timer callback is getting called before it completes the current task.

 Try placing a block at the start of the event so that any more events come in will get rejected.

 Use a writable constant for example inside the OnTimer event..

 Const Busy : Boolean = false;
   If Busy Then exit else Busy := true;

   // do your code...
  Busy := false;

Try that.

Title: Re: GDB Exception raised on Autosize
Post by: rborsey on October 06, 2019, 10:11:43 pm
Aha Jamie - I think you are on to something there . . .

This timer is activated only once a second and the app is not so busy that it should be a problem (although clearly in principle it could be) but what I do have is another much higher speed timer which is displaying a VU meter for the audio and this too updates the GUI . . . Anyway I'll make some experiments (and include a log of detected clashes) and get back with an update.

I have a thought though that if there is a potential problem with effectively asynchronous parallel events initiating a GUI refresh which could create this sort of problem then isn't there always the theoretical potential for a timer related update and a user operation (eg a click event) to create a similar conflict and crash?? If so how can I avoid it?

Cheers R

Title: Re: GDB Exception raised on Autosize
Post by: rborsey on October 06, 2019, 11:25:09 pm
An initial update - and of potential interest for anybody who has timer-based updates to visible components . . . .

Before that a HUGE thank-you to Jamie for his insight and his willingness to help . . .

I implemented a version of Jamie's suggestion, using globals rather than writeable const (as I have two timers running in parallel). The fast timer is clocking at a fast rate (for this test at 10ms) and the second is running once per second. In 4 minutes of runtime there were 6 recorded conflicts where both timers initiated GUI refreshes at the same time which would have caused a crash . . .

2nd test - repeated the run and this time I performed a manual event which also caused a refresh, clicking rapidly on a button which initiated a display action. It was easy to cause a crash . Not good. IMHO this is a bit of a bug in the implementation of the controls . . .

Next test will be using a critical section which I will invoke in the ontimer events and on any user control actions which can be performed while the timers are running (in the case of my app not all the time and not all controls). Outside of modifying the logic of the windows control software this would seem to be the 'proper' solution as in theory even using a variable as a control leaves a small race condition between testing the flag and setting its new value, and also means missing a timer cycle occasionally. Update to follow (tomorrow as in Europe it is time to sleep . . .).

Happy coding . . .

Title: Re: GDB Exception raised on Autosize
Post by: jamie on October 06, 2019, 11:56:20 pm
There is not much in the way of control bugs that you are going to fix..

 Most of the controls on the board are event driven so when something changes in them they post a message or get a posted message from the OS to perform some actions of notified the app of some actions that took place.
  If you don't allow these messages to process things can go wrong very quickly.

 I have a good idea of what you are doing as for code because I too have done lots of DSP coding using the sound system but I did not use any timers, I used the message notification of the media system when data was ready or buffers were empty etc..

 In your case I believe what you should be doing is using a single timer, maybe one that is of high resolution and then scale that within its Ontimer event. scale it to the 1 sec event you have and execute that code while there and then follow through with the high res timer code..

 Interacting with the controls at highspeed is going to get you in trouble. Anything you do that forces the controls to update is going to stall it.

 For live data updates I would directly paint to the screen and not do anything in the timer even that forces GUI updates.

 But this info should be kept in logged in the background via a DataRecord for example so when ever the user stops it or starts it, any GUI controls that need static updating can proxy with this record.
Title: Re: GDB Exception raised on Autosize
Post by: rborsey on October 08, 2019, 12:43:13 am
2nd update. Thanks again Jamie for your ideas.

So for the fast timer I have changed to direct screen updates as it is a VU meter. The one second updates are trickier but I have introduced logic to disable autosizing on these updates - they are too complex for direct paint. Anyway all seems fine although I clearly need to be careful. I still think there is a weakness if any non-user-initiated control update can potentially conflict with a user op and cause a crash . . .

Bonne nuit

TinyPortal © 2005-2018