Square: Stack overflow with Math.abs in Math Module

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Square: Stack overflow with Math.abs in Math Module

Dasso
Hello Every one !

As you can see in the below screen capture (in the 'Call Stack' zone) I have an error in the Math Module (more specifically in the function 'Math.multiply' when calling 'Math.abs').



The error say 'Stack overflow in Math.abs.2'. It is obvious that the error is that Math.abs call should be 'Math.abs 1' but what is weird is that this is in the Math module and I didn't compile this part it is a provided file. Nevertheless I open the Math module, I double check and there is no mistake in the call of 'Math.abs'.



By the way My Jack compiler seem to work well, I compare .vm files generated by my Jack compiler with .vm files generated by the provided Jack compiler on the Square folder, there is no difference except 'pop temp 0' instructions in the .vm files generated by the provided Jack compiler and a different way to handle if statement (with 'not' and 2 less labels).

To had in the difficulty to understand why It doesn't work perfectly. when I run the VM emulator I can move the box in all directions and I can use z and x but after fews seconds the stack overflow error in Math.abs happened.

I hope someone can give me some advises.

Merry Christmas from France.

Dasso
Reply | Threaded
Open this post in threaded view
|

Re: Square: Stack overflow with Math.abs in Math Module

cadet1620
Administrator
This post was updated on .
Dasso wrote
The error say 'Stack overflow in Math.abs.2'. It is obvious that the error is that Math.abs call should be 'Math.abs 1' but what is weird is that this is in the Math module and I didn't compile this part it is a provided file. Nevertheless I open the Math module, I double check and there is no mistake in the call of 'Math.abs'.
function Math.abs 0 is correct. The 0 is the number of local variables. Math.abs does not have any locals. On line 83 in your screenshot, you can see call Math.abs 1 where the 1 is the number of arguments.


[I must have been asleep when I wrote this.
cadet1620 wrote
It looks like you are getting a stack underflow. You can see that the SP is 2047 which is one lower than its starting value 2048.
The stack begins at 256 and 2047 is the maximum value for the SP. Address 2048 is where the "heap" for dynamic object allocation begins. --M]



Dasso wrote
By the way My Jack compiler seem to work well, I compare .vm files generated by my Jack compiler with .vm files generated by the provided Jack compiler on the Square folder, there is no difference except 'pop temp 0' instructions in the .vm files generated by the provided Jack compiler and a different way to handle if statement (with 'not' and 2 less labels).
I don't understand what you are saying about differences in pop temp 0.  They are critical to keep the stack properly aligned after do statements.

For example, if you do not do the pop after do, this code will stack overflow:
while (true) {
    do Math.multiply(0, 0);
}
It may be that something like this is what is actually happening, and the values displayed by the VM emulator were not correctly refreshed after the error message.

If you can not find the problem, feel free to mail me a .zip file with all the .vm files -- those generated by your compiler and the supplied OS files that you are using.

By the way, if you are not already doing it, it is quite useful to write the Jack statements as comments in your output VM files. This makes it much easier to find your way around in your generated code.

--Mark

Reply | Threaded
Open this post in threaded view
|

Re: Square: Stack overflow with Math.abs in Math Module

Dasso
Hello Cadet,

After adding 'pop temp 0' to 'do' VM instruction my VM code work perfectly on the VM emulator, therefore Big thanks Cadet.

This is the below exemple that you introduce to show off the danger of not cleaning the stack that really help me to understand.

while (true)
{
    do Math.multiply(0, 0);
}

Can we say that a  'stack overflow' error is a 'memory leak' error, the kind that crashes program on windows machine (or other OS) ?

Have a nice day.

Dasso

Reply | Threaded
Open this post in threaded view
|

Re: Square: Stack overflow with Math.abs in Math Module

ivant
Dasso wrote
Can we say that a  'stack overflow' error is a 'memory leak' error, the kind that crashes program on windows machine (or other OS) ?
Normally they mean different things. You already know about the stack overflow. In "real life" it is caused mostly by the code the programmer wrote, rather than a compiler bug. Most often it's due to a very deep or even endless recursion.

Memory leak happens when you allocate heap memory (think new Something() in Jack) and then forget to release it even when it's no longer used. If this happens in a function which is called often enough, the program may run out of memory and stop working. One cause for this is when functions "forget" to release internal resource before they end.

Another, and harder to fix one, is when it's hard to track who is the "owner" of this memory. That is, who is supposed to free it. Let's say A, B and C are functions. A calls B, B calls C, C produces some result in a newly allocated block (e.g. some string) and returns it to B. Now B is the owner of this block. Depending on some condition, B may pass this block to A as a return value, or it may just return another value. In the second case, B should also release the block, but the programmer may forget to do so.

What makes it harder is, that languages like C, C++ and Jack don't indicate who is the owner of the memory. This is something that the programmers have to take care of. In large programs, these kind of problems are almost inevitable to occur and are quite hard to find and fix.

There are other types of memory related problems as well. For example in languages like C and Jack you can "forget" that you freed the memory and still try to use it afterwards. This may even work OK in some situations, like if you're using it before the system allocated it for something else. You'll still be able to read the old data that can make your problem much harder to find.

Another type is buffer overflow, where you allocate an array (the buffer) where you want to put some kind of input, be it from the keyboard, of from file or network traffic. But you don't properly handle if the input is larger than the allocated buffer and write past it. This kind of bugs are very useful to gain arbitrary code execution and even admin rights.

A different type of problem is memory fragmentation. This normally happens when a program runs for a long time. It allocates and frees chunks of memory with different sizes. And let's say it has no memory leaks. It can still run into problems, because the free memory is not in large continuous chunks, but rather in many small ones. When the program needs a new chunk of memory the allocation function may not be able to find suitable hunk of free memory, even though there is enough of it.

Even if it can find it, the time it takes to do so, can start to rise over time and make the program run slower and slower.

Many of these problems can be fixed or at least greatly reduced by using higher level languages with automatic memory management (aka garbage collectors). They have different kinds of problems though, so, as is often the case, it's about trade-offs.