How to debug effectively Memory.alloc

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

How to debug effectively Memory.alloc

berenger
Hello everyone, I was all too elated to have a seemingly bug-free Jack compiler in chapter 11.
Then I ran into Project 12 and hit a wall called Memory class.
My alloc function overflows the heap when called by other OS functions (Output.createShiftedMap is particularly nasty).
The problem lies in the fact that I don't really know these other calling OS functions too well to catch the error with the breakpoints on VM code in the VMemulator.
Even worse, if I try to print on screen debugging comments to see the function progress out of the VMcode, by writing

do Output.printInt(PROBLEMATIC_ADDRESS);    // prints suspect critical address
do Output.printChar(32);                              // space

...Output class calls String class which in itself needs Memory.alloc, so it will throw a strange recursive error.
So this is particularly troublesome, because the bug is hard to spot with the current debugging tools.

I spent the better part of 2 months completing the book but the level of difficulty reached here really feels like too much for my capabilities (I am an industrial engineer handling code in Fortran and C++98), and right now I am quite disappointed, feel like caving in.
Reply | Threaded
Open this post in threaded view
|

Re: How to debug effectively Memory.alloc

ivant
As the authors of the book wrote, you should be able to finish all the projects with implementing a very simple alloc, which just allocates from the empty block, and free, which does nothing. You can start with that and confirm that it works.

One easy way to add some debug info to your alloc function is to designate some memory (let's say 10 bytes) in the start of the heap, and put there meaningful values. For example, you can maintain a count for how many times alloc was called, how many times free was called, how many bytes were requested (total) and how many bytes were freed (again, total). Or some other relevant info, that you might find useful.

If you want to write to the screen, you must take care to only use non-allocating methods. Alternatively, you can have a flag, which tells the allocator whether to print or not. Something like that:
class Memory {
    var boolean printDebug;

    function void init() {
        let printDebug = true;
       ...
    }

    function int alloc(int size) {
        if (printDebug) {
            let printDebug = false;
            do Output.print(....);
            let printDebug = true;
        }

        ...
    }
}
(Sorry, my Jack-fu is a bit rusty. This may be written in a more elegant way.) Note though, that String constants in Jack are replaced with String constructor at the place of the call. This means that if:

do Output.printString("Hi");

is equivalent to

do Output.printString(String.new(2).append(72).append(105));

The memory of the constructed string is then "lost". That is, it's still marked as used, but its address is forgotten. This is called a memory leak. To prevent it, you can do two things: allocate the strings you need in the init method. This way you can reuse them. Or assign the string to a variable and dispose of it after use. In the Memory class, I strongly recommend the former.
Reply | Threaded
Open this post in threaded view
|

Re: How to debug effectively Memory.alloc

berenger
Thank you for the quick response and the tips.

Interestingly, a very stripped down, 4 lines (included return)-long Memory.alloc version of the type all_block = free_list, free_list = free_list + size handily passes the provided test.

The problems come with
*allowing the free_list to leap from address segment to address segment
*managing the allocated blocks and removing them from free_list; updating the free_list accordingly.

I would post my code here for Memory.alloc to show how I tried to handle the issues above, but it's forbidden and I wouldn't want to waste anyone's time in trying to debug it.
In any case, thank you again for the tips.

Reply | Threaded
Open this post in threaded view
|

Re: How to debug effectively Memory.alloc

ivant
You can email it to me and I'll take a look. Just click on my name and choose the send email option.
Reply | Threaded
Open this post in threaded view
|

Re: How to debug effectively Memory.alloc

berenger
Cheers, just sent.
I hope the indenting did not turn out too messed up.