Posts: 615
Threads: 49
Joined: Feb 2009
Reputation:
2
I made a snapshot from my game I currently write. On level 4 after 6 moves it came with a out of memory error, but the code is not different from levels 1-3, where it works well. I suspect a memory leak. The included snapshot is just short before it happens (Controls: QAOPM). I can PM the source too. The same thing happen with Heap size 256 or 1500.
Level4_1.zip (Size: 9.44 KB / Downloads: 758)
Posts: 97
Threads: 23
Joined: Jul 2011
Reputation:
0
It happened to me during O-cman's development. I got this error because I putted a GOTO instead a GOSUB inside a SUBroutine, something like this:
10 REM main loop
20 stuff to do
30 GOSUB 100
90 GOTO 10
100 REM this is a SUB
110 stuff to do
120 GOTO 200
130 RETURN
200 REM this is another SUB
210 more stuff to do
220 RETURN
Line 120 must be GOSUB and not GOTO, that's why I got the Out Of Memory error. I don't know if this your case, but at least I hope it gives you a clue.
Cheers
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
oblo Wrote:It happened to me during O-cman's development. I got this error because I putted a GOTO instead a GOSUB inside a SUBroutine, something like this:
10 REM main loop
20 stuff to do
30 GOSUB 100
90 GOTO 10
100 REM this is a SUB
110 stuff to do
120 GOTO 200
130 RETURN
200 REM this is another SUB
210 more stuff to do
220 RETURN
Line 120 must be GOSUB and not GOTO, that's why I got the Out Of Memory error. I don't know if this your case, but al least I hope gives you a clue.
Cheers
The code above is also ok, and should not produce any error. During execution time, every gosub must end with a return (to avoid stack overflow). Other than that, they needn't to be "balanced". If you execute the code above, it should work ok. :roll:
Posts: 97
Threads: 23
Joined: Jul 2011
Reputation:
0
boriel Wrote:The code above is also ok, and should not produce any error. During execution time, every gosub must end with a return (to avoid stack overflow). Other than that, they needn't to be "balanced". If you execute the code above, it should work ok. :roll:
Maybe with the current version of ZX Basic, but with the a month ago it gave Out of Memory (and 3 Subscript wrong). Remember that it was that happened with version 0.8? The only thing that I changed was that: a GOSUB instead a GOTO.
Cheers
Posts: 615
Threads: 49
Joined: Feb 2009
Reputation:
2
I will check it again, and dramaticaly reduce the amount of gotos and gosubs later today. Maybe there are too many of them. After I added another gosub yesterday, I got the error already in level 2. I think, oblo is right, with gosub. Maybe a memory leak.
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
LCD Wrote:I will check it again, and dramaticaly reduce the amount of gotos and gosubs later today. Maybe there are too many of them. After I added another gosub yesterday, I got the error already in level 2. I think, oblo is right, with gosub. Maybe a memory leak.
It shouldn't be a memory leak, but a "Stack leak". GOTO == JP; RETURN = RET. It's pretty straightforward for the compiler.
I will add a "Stack check" flag to trap this.
Maybe your ORG is too low. Try setting it to ORG=30000 :?:
Posts: 615
Threads: 49
Joined: Feb 2009
Reputation:
2
boriel Wrote:LCD Wrote:I will check it again, and dramaticaly reduce the amount of gotos and gosubs later today. Maybe there are too many of them. After I added another gosub yesterday, I got the error already in level 2. I think, oblo is right, with gosub. Maybe a memory leak.
It shouldn't be a memory leak, but a "Stack leak". GOTO == JP; RETURN = RET. It's pretty straightforward for the compiler.
I will add a "Stack check" flag to trap this.
Maybe your ORG is too low. Try setting it to ORG=30000 :?: Okay, but you have already debug memory option. Can you not include the stack check to it? Or it it will be a independend stack check option, with live-display of stack size displays at given position every 1 second?
e.g.: DEBUG AT 23,0;#StackUsed (compiling it in normal mode obmits it and does not calculate the system information values, but compiling in -debuger mode display all DEBUG messages like print, and calculate system informations or variables, which can be then displayed).
I think, this could be a nice feature request
#StackUsed returns the currently used size of stack
#StackMax returns maximum size of stack
#StackFree returns free memory left on stack
#HeapFree returns free memory on Heap
It is true, I put my stack very low in the memory to gain room for my games, will try today to put it higher or lower to check if it changes anything.
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
The problem is, there is no stack zone. Stack is SP register. It's set automatically by the BASIC loader with the CLEAR statement (just below the ORG of your program). SP always grows downwards with each PUSH. When SP reaches 236XXX, for example, it's entering the ROM Variables area which are written very often (e.g. the FRAMES updates 50 times/sec), crashing your program.
A check could be comparing SP with a stack bottom mark (e.g. BASIC area Zone), or so, and raise an ERROR if SP gets into such area.
Posts: 615
Threads: 49
Joined: Feb 2009
Reputation:
2
boriel Wrote:The problem is, there is no stack zone. Stack is SP register. It's set automatically by the BASIC loader with the CLEAR statement (just below the ORG of your program). SP always grows downwards with each PUSH. When SP reaches 236XXX, for example, it's entering the ROM Variables area which are written very often (e.g. the FRAMES updates 50 times/sec), crashing your program.
A check could be comparing SP with a stack bottom mark (e.g. BASIC area Zone), or so, and raise an ERROR if SP gets into such area. Exactly.
I know, knowing the lowest possible adress that can be used, the actual stack pointer and original stack pointer (stored by clear in system variables) or display current Stack pointer can help to determine how much can still be used, and if I play my game and watch how the stack pointer is going down, I know, oops, there may be something wrong with gosub.
We must also not forget that some interface like Opus or interface one add more system variables and so raises the address of BASIC too.
Posts: 615
Threads: 49
Joined: Feb 2009
Reputation:
2
Thanks oblo! I just replaced one Gosub with goto and it works now even with ramtop lowered to 24050. So it was my fault.
Posts: 1,770
Threads: 55
Joined: Aug 2019
Reputation:
24
LCD and oblo, we need to FIX this.
Please, pass me a source code which fails. I need to check what's going on.
Theoretically only writting unbalanced gosubs like this one should produce a stack overflow:
Code: 10 REM Program....
20 ...
30 GOSUB 100
...
...
100 Bla bla bla
150 GOTO 10
160 RETURN: REM Never reached
So I need to now what' happening. E.g. LCD, it could be of great help if you can "minimize" your code which reproduces error.
Otherwise, please someone send me any code to check it.
But it's my bet (a beer! ;-)) that you'are returning from a GOSUB with a GOTO, instead of RETURN.
Posts: 97
Threads: 23
Joined: Jul 2011
Reputation:
0
Boriel, I've just sent to you the code that failed. And yep, if I can recall correctly, my fault was that: a bad GOSUB/GOTO/RETURN combination :?
Cheers
Posts: 615
Threads: 49
Joined: Feb 2009
Reputation:
2
oblo Wrote:Boriel, I've just sent to you the code that failed. And yep, if I can recall correctly, my fault was that: a bad GOSUB/GOTO/RETURN combination :?
Cheers Mine too. I changed the code in the last 3 years that much, and forgot that it was not a subroutine but that it was returning with a Goto again. So in fact it was not a compiler bug. RETURN was just not done.
|