Crash in BASIC program
Alan Adams (2486) 1149 posts |
Hi I have a weird crash in a BASIC program. It occurs in a FN that’s already been called about 20 times. I have increased the WIMP slot, which had no effect. At the start of execution, *reportmem shows: *reportmem immediately before the function call says: It seems to me to be stack-related, but I can’t see how. Any ideas? |
Steve Fryatt (216) 2105 posts |
Memory corruption, where some other bit of the program is writing to memory that it shouldn’t be? |
Martin Avison (27) 1494 posts |
Agreed! I suggest trying |
Alan Adams (2486) 1149 posts |
Thanks Martin. That reported “BASIC lists have bad pointers.” A check on the help showed Reportmem L which listed loads of things, ending with main%, followed by the error message. main% is a window handle, set up by loading a template file. Immediately before that a text buffer is DIMmed, and that is the buffer used for text from the template. This error started when I increased the size of one icon’s text from 7 bytes to 10 bytes. Increasing the size of the text buffer fixed it. |
Steve Fryatt (216) 2105 posts |
If only the Wimp had a way to allocate the indirection buffer to the size of the data in the template file…
Untested… it’s ripped from two separate routines in a more complex Wimp Library scenario. There’s a presumption that something, somewhere has already done
first, to allocate the template name buffer. I’m never sure whether this is actually necessary if the program won’t be passing Edited to remove stray variables from the original code. |
Martin Avison (27) 1494 posts |
As Steve says, always get the space required before the DIM, for Templates (& other things) if possible. Programming to cope with change! But nice to see that Reporter helped to identify your problem … I added the list validation when I had similar confusing problems, and it has been invaluable here on occasion. |
Alan Adams (2486) 1149 posts |
I’ve got checks in place within the load template code. It turned out that the buffer was also being added to when I copied templates, and that routine didn’t have limit checks. That’s where the crash originated. It now has limit checks. Ideally I would have a way to find the buffer space used within each of the icons in the template, before loading it, then allocate that much space multiplied by the number of copies of the icon I am going to produce later. As it is, it’s using a constant value, and it relies on the limit checks to tell me when I need to change the constant. It gets a bit more messy when the icon has a validation string, as there’s nothing in the template to indicate the buffer size allocated for that, other than the length of the validation string within the template. I need to work out a suitable length when copying the icons, to accommodate dynamic changes to the string. |
Stuart Swales (8827) 1357 posts |
Do you dynamically change the validation strings or can they just be shared amongst different instances of the same class of icon? |
Martin Avison (27) 1494 posts |
How about loading the template, finding the space used by the icon(s) buffer & validation, then allocating a new buffer for the maximum icons that you are going to create? The created icons do not have to be in the same buffer as the originals. Indeed, if the validations of the created icons are to be the same as the originals, just point the created ones at the originals. That way you save space. (which is expanding on the questions from Stuart, I think). |
Alan Adams (2486) 1149 posts |
Yes. For example changing the text colour with an outline font.
I do that in some cases. This code is used to produce a table, whose row count is determined at runtime, and can be altered while the program is running. I was simply creating a single row of icons in the template, then copying it down. This had a couple of disadvantages, notably that the first row was different in things like buffer allocation from the copies, and the icon numbers in a column could not be contiguous. Now I still create the icons in the template, but after loading the template, reduce the icon count in the window description to hide them. The template icons are copied to an area of memory that I control. The first column can then be created by adding copies of a single icon to the window with Wimp_CreateIcon, increasing the buffer usage for both text and validation string as I go. This is them repeated for the other columns in turn. This became an essential method for the window I was having trouble with just now, as it has two tables side-by-side, with different numbers of rows, since the icons are diffeent heights. It turns out that my estimate of the required buffer size was almost exactly right, so that when I increased the text buffer in just one of then prototype icons from 7 bytes to 10 bytes, the copied icons overwrote the allocated memory, and trashed the window handle. This produced a number of strange symptoms, among them *Reportstack crashing, trying to read a text string from the result of Wimp_GetWindowInfo giving an abort, and as in the initial post, LOCAL giving an abort. As suggested, the cleanest solution is to load the template, using the call to find out whether it will fit (I do that already), then calculate the buffer size needed for the copies using the data from the template. |
Steve Drain (222) 1620 posts |
It is a very long time since I used Templates, but I think that once you have loaded correctly, with the right indirected string buffer, I do no think there is anything stopping you from pointing an icon text at another buffer, and the same for a validation string. If you do not preserve the original pointer you will loose that memory, of course. |
Martin Avison (27) 1494 posts |
After an overwrite, the results are predictably totally unpredictable! All sorts of confusing things can happen … but may not be for some time. |
jan de boer (472) 78 posts |
Re:If only the Wimp had a way to allocate the indirection buffer to the size of the data in the template file… |
Alan Adams (2486) 1149 posts |
It wouldn’t have helped here, but would be useful other times. There is an option to call Wimp_LoadTemplate to ask whether the data will fit, before actually loading. The latest crash was eventually traced to calling Wimp_GetWindowInfo with too small a buffer. (The number of icons in my windows is being changed on the fly.) Calling Wimp_GetWindowState first wouldn’t help, as that call doesn’t return the icon count. If it did, calculating the required buffer size would be easy. (92 + iconcount*32) |
Martin Avison (27) 1494 posts |
I thought Wimp_GetWindowInfo,,handle% OR 1 returned the number of icons in the window (or rather icon blocks allocated), but without the actual icon blocks themselves? |
Alan Adams (2486) 1149 posts |
That isn’t very clear from the description in the PRM, but yes, it would appear that’s what it means. Next entertainment – I want to have some icons switch from visible to invisible. I do it by setting or clearing bit 23 in the flags (the deleted bit). It didn’t work for the last icons – setting the bit removed them completely from the definition. Wimp_DeleteIcon does describe this behaviour, but just setting the deleted bit does the same. I’ve fixed it by adding a redundant icon at the end of the window definition, slightly off-screen, and with both colours set to grey01. It would be better if the flags included a “hidden” bit. |
Stuart Swales (8827) 1357 posts |
Not much room in there, is there ;-) |
Steve Fryatt (216) 2105 posts |
There is… I could have sworn that someone posted a template load routine that did just that earlier in this very thread… :-) |
Alan Adams (2486) 1149 posts |
Here’s the one I’ve been using for years. However replacing all the Wimp_GetWindowInfo calls with something similar is more than I want to take on at the moment.
|