Archive for July, 2008

MegaZeux Debugging: part 3

Wednesday, July 30th, 2008

After some more fiddling, basic robot watching is pretty rock solid.  I fixed some memory leaks and crashes, and I’ve moved on to breakpoints.  And herein lies the conumdrum, as I’m trying to figure out the use cases here and how everything should work together.  As it stands, breakpoints are not very useful, because you can only place them when debugging, and then the only option is to place a breakpoint at the currently executing line.  The robot editor that shows up when debugging currently has no mechanism for scrolling around the robot’s code, so you’re limited to the view of about 10 lines of code that surround the current line.  For breakpoints to be useful to a developer, I feel like either you should be able to place them either in editing mode (when you’re actually modifying the robot), which will lead to all kinds of terrible headaches trying to keep that information in sync with the robot’s contents, or else the debugging interface needs to have more interactivity.  I’m leaning towards the latter option, but still open for discussion.

The other major consideration right now is what kind of lifetime breakpoints should have.  Should they persist between debugging/testing sessions?  Across boards?  What should happen to the interface when the player switches boards and the debugged robot no longer exists?  These are questions for which I don’t have good answers at the moment.

MegaZeux Debugging: part 2

Monday, July 28th, 2008

What with midterms and end of term, it’s been several weeks since I last touched my robotic debugger, but that changed tonight.  There’s now a usable bleeding-edge debugger for your perusal in the bzr repository.  You have your choice of robots to watch on activation (ctr+f6 in testing mode), f8 will bring up the watch dialog, f9 will step a single instruction (which updates in the editor accordingly, so you can follow the action), and f10 will continue normal execution with the debugger still activated, so pressing f9 will start stepping once more.  Of course I’ve somehow induced megazeux to start segfaulting on exit, so there are obviously some problems that need fixing, but everything starts somewhere!

Testing linked lists

Sunday, July 27th, 2008

I’m just finishing up the CS 136 class here at the University of Waterloo, which also goes by the name of “Elementary Algorithm Design and Data Abstraction.” In other words, we make the transition from introductory Scheme to introductory C while learning about topics such as braun trees, hash tables, and more. We’re also expected to use test driven design, or at least write tests and run them frequently, to ensure that our assignment programs are working correctly. While most of the programs are rather elementary, the procedure to test data structures such as linked lists is rather annoying, because it ends up looking something like this:

int i;
int testNum[] = {0, 1, 2, 3}; List *l = list;
for(i = 0; i < sizeof(testNum)/sizeof(testNum[0]); i++)
   assert(list->val == testNum[i]);

No imagine writing that over and over, especially if you have multiple fields that need testing. Being unsatisfied with this setup, I took it upon myself to write a linked list field asserter, which can be used like so:

int cmp_num(void *a, void *b)
{
    return (int)a – (int)b;
}

int testNum[] = {0, 1, 2, 3};
assertListFieldEqual(list, offsetof(List, val), cmp_num, testNum, sizeof(int), offsetof(List, next));

As you can guess, it’s about as generic as you can get in straight C without the benefit of C++ templates. If you have a structure that is traversed via a pointer to the next structure, it can be asserted with this system. assertListFieldEqual takes

  • a pointer to the head element
  • offsetof(list type, field to compare)
  • a pointer to a comparison function
  • a pointer to a list of expected values
  • the size of a value
  • offsetof(list type, traversal field)

The function itself is not particularly difficult, but it does abuse pointers in very unethical ways:

typedef int (*cmp_func)(void *, void *);

void assertListFieldEqual(void *list, ptrdiff_t field, cmp_func cmp, void *cmp_to, size_t cmp_size, ptrdiff_t next)
{
    ptrdiff_t count = 0;
    while(1)
    {
        assert(!cmp((void *)(*(ptrdiff_t *)(cmp_to + count * cmp_size)), (void *)(*(ptrdiff_t *)(list + field))));
        if((void *)*((ptrdiff_t *)(list + next)) == NULL)
            break;
        list = (void *)(*(ptrdiff_t *)(list + next));
        count++;
    }
}

I’m pretty sure all of my pointer abuse is fully sanctioned by the standard, so it should be portable to my knowledge. Therefore, go forth and multiply, and test your lists well! And if you’re in any doubt that this is not generic enough, behold, I give you string comparison!

const char *testName[] = {"1", "2", "3", "4"};
assertListFieldEqual(list, offsetof(List, name), (cmp_func)strcmp, testName, sizeof(char *), offsetof(List, next));

MegaZeux Debugging

Monday, July 7th, 2008

I’m an occasional contributor to the MegaZeux source code, and I frequently compete in the bi-annual Day of Zeux competions.  Accordingly, I’m always interested in new ways to push MegaZeux forward and help people create games easier, which brings me to Kev Vance’s MegaZeux debugger.  It’s ten years old and based on the ancient 2.51 codebase, which means that the released code is not much good (2.7 was a near complete rewrite, if I recall correctly), but it’s got me thinking about how a debugger could integrate into the modern incarnation of mzx.  So much so that I’ve got a prototype in the works (and a corresponding bzr repository), and some thoughts to put down on paper.

I forsee a debugger in MegaZeux as being useful in the following ways:

  • Tracing code execution in a single robot
  • Placing breakpoints in robotic code
  • Verifying expected values at different points in the program

The third is already possible with the F11 window that was added recently, which displays all known counters for easy perusal.  Combined with instruction stepping, a debugger will hopefully remove the need for debug variable output lines in order to determine when a counter’s value changes.

The vision of the robotic debugger I have is a shortened robotic editor that takes up half the screen.  This displays the watched robot’s program with the current line highlighted.  F9 will single step forwards in the current robot, F10 continues the normal execution until/unless a breakpoint is reached (in any robot).  Pressing CTR+F6 will bring up the debugger interface, and a window to select the robot to watch, at which point all execution will cease until the user presses either F9 or F10.

That’s the gist of it right now.  I currently have the shortened editor displaying the watched robot code, but only the global robot can be watched right now, and the code display doesn’t actually show which line is about to be executed.  If you bring up the debugger, all robot execution stops, and pressing F9 will trigger one line of code to be executed in the global robot, and F10 will make everything resume as normal.

Now, a brain dump of problems that I need to consider, in no particular order:

  • Remove the ability for the player to move when single stepping?
  • In fact, currently the rest of the board is updated as usual while the debugger is active, so bullets will continue to move normally even when the user is single stepping a robot, so something has to change there.

I’m positive there are going to be more concerns I’ll have to deal with, but I’m pleased with the progress I’ve made so far.  Next step: make the debugger show the actual line being executed.  Then it might start being useful!