Sunday, April 27, 2008

Super! Delegates

I have added support for D programming language delegates to the ZeroBUGS debugger!

And I am in the process of rolling out beta binaries, and a new release for Ubuntu 8.04 (Hardy Heron).

Happy (Eastern Orthodox) Easter!

Tuesday, April 15, 2008

Is it the Blogosphere, Stupid?

Oh Lord, it is so hard and stressful being a blogger; and poor bloggers may die of stress. This is what some recent "breaking news" wants you to believe.

First of all, stress is bad for one's health in any activity (I almost wrote "line of work"), what's the big news?

Secondly, blogging may beat doing real work but it is not work. Who the fudge are we kidding? It's like saying that keeping a journal is work. No, you just jot down ideas or things that you find interesting or worth capturing (perhaps when you wind down at the end of the day). You write about a project you are working on, a hobby, or something that bothers you; or something meaningful in your life.

How many people do you know that are enjoying some level of success (politicians, writers, software engineers, doctors, lawyers, you pick) who blog several times a day, every day? Ok, politicians may be a bad example since they have minions blogging for them.

Web 2.0 turned blogging into a full time "job"; self-proclaimed experts "cover" the markets, the political scene, celebrity gossip, and technology. When have these people had any time to build any expertise when every single day they blog till they drop? Do they ever stop and think about what they are writing or merely smell each other's farts?


Instead of building things (and, why not, selling for a profit), modern society "generates content", begging for somebody's mouse click; and then everybody and their grandma complains (in a blog) about the economy being in decline.

And I bet that whatever few mouse clicks this blog entry has trapped, they are coming from hungry blogger dudes, avidly searching the internet for ideas to expertly comment on. Dude, put your flip-flops on and go get a job. A real one.

Thursday, April 10, 2008

An Exceptional Chain of Events

It was said of yore that throwing an exception from a C++ destructor is a verie wycked and wofull thyng.

Remember goto? Some distinguished gentlemen of the C++ programming trade look down on throwing from destructors as being eviler than using a goto. Standing base for such moral a judgment is that "a throwing destructor makes it impossible to write correct code and can shut down your application without any warning" .

Destructors in C++ are one essential ingredient to the Resource Acquisition Is Initialization (RAII) idiom, which can be resumed as follows: Resources (i.e. memory, sockets, file handles, etc) are acquired during the construction of an object. If an exception is thrown from anywhere in the code during the lifetime and after the object has been fully constructed, the C++ language rules guarantee that the object's destructor will be summoned.

Thus resources can be released gracefully and graciously by said destructor, even in the distasteful and exceptional eventuality of... an exception. The Programmer is relieved from the burdensome duty of having to release resources on every single possible code path.

RAII relieves the programmer from manually preventing leaks.
(Notice how nicely relieves and leaks go together).

If a destructor, invoked as part of the automatic cleanup that entails the throwing of an exception, decides to throw its own exception, then the system has but two choices: to go into an ambiguous state (now there are two outstanding exceptions, the original one, plus the destructor-thrown one) or... throw the towel.

It is C++ Standard behavior to follow the latter course: the towel is thrown from around the waist, the user is mooned and the program calls terminate(). Hasta la Vista, Baby. And for this reason, they say your destructors should never throw.

But what if there's not way to recover?

Let's consider a generic Lock object which may look something like this:


template<typename>
class Lock : boost::noncopyable
{
T& mx_;

public:
~Lock() throw()
{
mx_.leave();
}
explicit Lock(T& mx) : mx_(mx)
{
mx_.enter();
}
};

The problem with the code above is that T::leave() may throw an exception (it may as well not throw, but one really cannot tell, since T is a template parameter).

An so I come to the conclusion of this post. I assert that the code above is just as good as it gets. Of course, T may be bound at compile time to a class that implements the leave method somewhat like this:

void Mutex::leave()
{
if (int resultCode = pthread_mutex_unlock(&mutex_))
{
throw pthread_runtime_error(resultCode);
}
}

If unlocking the resource fails, then a) something really bad must've happened (possibly a memory corruption?) and b) there is little, if anything, to do about restoring the system to a stable state.

I say let ye programme crash and burne.

What do You reckon?

Friday, April 04, 2008

Test Drive: GCC 4.4.0

I have finally gotten around to test ZeroBUGS with a C++0x supporting compiler.

Even though said support is labeled as experimental and is not activated by default (-std=c++0x in the command line does the trick), GCC 4.4.0 seems to be working just fine. Or I should rather say that Zero seems to be debugging GCC 4.4.0-generated code just fine.

I have installed the latest compiler snapshot on a Ubuntu 8.04 beta system, by simply typing apt-get install gcc-snapshot (apt is the awesomest).

Then I set the compiler to /usr/lib/gcc-snapshot/bin/g++ in my environment and fired up a battery of automated tests.

I also did a bit of manual testing for variadic templates, using code samples straight out of Wikipedia, and one quick test for rvalue references. Things look good so far.

Surprisingly, all unit tests having to do with floating point variables passed.

I may have to look deeper into these tests, since as stated here,
"Starting from GCC 4.3.1, decimal floating point variables are aligned to their natural boundaries when they are passed on stack for i386."

I will keep you posted.

Thursday, April 03, 2008

Random Log Entries

Ten years ago I used to carry a bulky day planner, and like in a Seinfeld episode almost bought a man-purse for it.

My handwriting sucks. I hear some schools are dropping cursive from their curricula.

Keyboards.

Instant messaging (thumbs up for opposable thumbs!)

Digital scrapbooks. Cloud(ed) computing memories.

Virtual social networking.

What will future historians and archaeologists think of us if the decoder ring for the Internet is lost?

Songs about programming that I would like to hear:
  • In a software continuum (you are my Heisenbug)
  • Perpetuum beta mobile
  • The universal constant is volatile (in C flat)
  • Debuggers don't step in the same river twice
  • Flossing bugs at dawn
  • Recombobulate (your shattered assertions)

Sunday, March 30, 2008

The Final Bugs

The commercial version of ZeroBUGS for Ubuntu Linux has been updated with a new custom look and fixes a couple of minor bug.

Coming up next in the pipe line are a professional edition (bundling 32 and 64 bit versions) and an enterprise edition (with a multiple seat license).

And I will continue experimenting in the beta branch with support for the D language. In fact, I just have received a test build of DMD 2.014 which should fix the DW_TAG_module issue which I discussed in a previous post.

Thursday, March 27, 2008

Wishing for Some German Engineering

After giving a try to OpenSuse 11 alpha 3 today, which its EULA calls (optimistically?) a BETA, it hurts me to say that I am disappointed.

Some minor cosmetic issues aside (fonts that do not align properly on my laptop screen) I could not install the darn thing.

The graphical installer kept saying that there are 0 packages selected for install, which will take just about 0% of my drive space. Really? No kidding.

And some lists and menus displaying in stylish white on white enhanced my experience (read: confusion).

It is however a big improvement over Ubuntu 8.04's beta, since Suse at least boots up on my laptop. The main reasons I would love to have a working OpenSuse installation are:
  • currently, the lappy runs Mandriva 2007.0 and I love French engineering like a dead escargot in my coffee;
  • Suse 11 is supposed to come with Gnome 2.22 and I want to check out the API improvements in gtksourceviewmm 2 (since the gnome 2.0 version left out important features such as markers);
  • Suse 11 promises GCC 4.3, which has exciting features such as variadic C++ templates;
  • I love the Green Graphics!
But I guess bullets two and three are also feasible with Hardy Heron (although GCC 4.3 is not the default compiler, and you have to invoke gcc-snapshot to get to it).

But then again, Ubuntu hates my DV6000z laptop. Or vice versa.

Tuesday, March 25, 2008

Debugging D Unit Tests

I had one slide in my presentation at the D Programming Language Conference last year that demonstrated how to automatically insert breakpoints at all unit test functions in a D program (using, of course, the ZeroBUGS debugger for Linux).

The trick mainly consists in invoking a small Python script at startup:
zero --py-run=dunit.py
where the contents of dunit.py may look something like this:

# dunit.py
import os

import re
import zero

def on_table_done(symTable):
extension = re.compile(".d$")
process = symTable.process()
module = symTable.module()

for unit in module.translation_units():

if unit.language() == zero.TranslationUnit.Language.D:
name = os.path.basename(unit.filename())

i = 0
while True:
symName = "void " + extension.sub('.__unittest%d()' % i, name)

print symName
matches = symTable.lookup(symName)
if len(matches) == 0:
break
for sym in matches:
process.set_breakpoint(sym.addr())
i += 1

(see http://zero-bugs.com/python.html for more information on the scripting support in the debugger).

This contortion is painful but necessary with D, because unit tests have the interesting property of running before anything else in the program.

Without this bit of gymnastics, by the time the debugger (trusted hunting companion) is wagging its tail at the main function, the unit test functions have long completed (or failed).

The script line shown above in bold (which constructs the symbol name of the unit tests) is now broken because of a change in the D 2.0 language. The name is prefixed by the module, as explained here: http://www.digitalmars.com/d/2.0/hijack.html

What happens is that the scripts is looking for functions named
void Blah.__unittest0() , void Blah.__unittest1() , etc whereas they are now called void mymodule.Blah.__unittest0(), void mymodule.Blah.__unittest1(), and so on.

Before, I could synthesize the symbol names to look for, but now this is hardly possible since there's no place to infer mymodule from, unless the compiler produces the (standard) DW_TAG_module DWARF debug info entry.

Unfortunately the DMD compiler does not generate a DW_TAG_module, and so it is almost impossible for the debugger to determine the module name. One possible hack would be to sniff other symbols in the module and look at their prefixes.

Or we could change the script like so:

import os
import re
import zero

def on_table_done(symTable):
extension = re.compile('.d$')

process = symTable.process()
module = symTable.module()

for unit in module.translation_units():
if unit.language() == zero.TranslationUnit.Language.D:
matches = symTable.lookup("_moduleUnitTests")
if len(matches) == 0:
break
for sym in matches:
process.set_breakpoint(sym.addr()


This stops the program in the debugger a couple of function calls before the unit test functions are executed. However it is not ideal since now we have to step over a bunch of assembly code.

Ideally, the D compiler should produce DW_TAG_module info.

Or the debugger could look up symbol names by regular expressions, but I have to punt on the performance implications of such an approach.on the performance implications of such an approach.on the performance implications of such an approach.

Sunday, March 23, 2008

yywrap it up

This weekend I decided to download the beta version of the highly anticipated Ubuntu 8.04.

After installing it on a virtual machine I promptly proceeded to building ZeroBUGS on it.

And I ran into a small roadblock: The debugger has a built-in C/C++ interpreter, for evaluating simple expressions and function calls. This code failed to link, because in this new Hardy Heron version of Ubuntu the yyFlexLexer class (see /usr/include/FlexLexer.h) has a virtual method called yywrap(). In older versions of flex yywrap used to be a standalone, extern "C" function.

To work around this issue in a portable manner I defined a new function in my configure.ac file.

It attempts to compile a small C++ program that assigns a pointer to method. If the compilation fails, I assume that yyFlexLexer::yywrap is not defined.

Here's the code:

AC_DEFUN([AC_YYFLEXLEXER_YYWRAP],
[AC_CACHE_CHECK([for yyFlexLexer::yywrap],
[ac_cv_yyFlexLexer_yywrap],
[ac_cv_yyFlexLexer_yywrap=false
cat > tmp.cpp << ---end---

#include <FlexLexer.h>
int main()
{
int (yyFlexLexer::*method)() = &yyFlexLexer::yywrap;
return 0;
}
---end---
if g++ tmp.cpp 2>/dev/null; then
ac_cv_yyFlexLexer_yywrap=true
rm a.out
fi
rm tmp.cpp])

if test "$ac_cv_yyFlexLexer_yywrap" = true; then
AC_DEFINE([HAVE_YYFLEXLEXER_YYWRAP], [1],
[Define if yyFlexLexer::yywrap is declared])
fi
])


AC_YYFLEXLEXER_YYWRAP


And you can test drive a pre-release of ZeroBUGS for Ubuntu 8.04 here: http://zero-bugs.com/8001/releases/zero_1.12-heron-032308_i386.deb

The md5sum is: 5b80e9f0f867b858620c740096e432dd

Saturday, March 22, 2008

__attribute__((language_safety("on")))

Musing over Bartosz Milewski's Safe D article, I was a bit surprised to learn how much effort programming language designers are putting into building safe language subsets.

A safe subset aims to prevent users from committing such unspeakable atrocities like buffer overruns, and dereferencing invalid pointers.

It is also surprising that a vast majority of C++ developers (and ex C++ developers that defected to C#) consider C++ to be an unsafe language. From my few data points, these are folks that have picked the language in the mid 90's and never updated their skills (they are still running their brains on Windows 95, so to speak).

I see developers grouped in two main schools: the low level C guys (encompassing the Linux crowd) and the Java / .NET corporate code monkeys.

Not a productive bug writer myself (on a good week I turn about five) I may not be qualified to speak. It has been a long time since I overran a memory buffer. These days most of my bugs have to do with multi-threading.

From the day I have switched from C habits to the C++ style of using STL containers and smart pointers my buffer overruns have decreased to zero Kelvin.

Shared_ptr (in either its boost or TR1 incarnation) is another useful friend.

Northwest C++ Users Group hosted a very good presentation on Wednesday: Stephan T Lavavej did an impressive tour of shared_ptr, useful both to beginners and to the more seasoned developers.

As an event coordinator, I had the chance to chat with Charles Zapata of Ontela, a hot up and coming downtown Seattle startup (who generously sponsored the Wednesday night meeting).

After the talk, Bartosz, Andrei Alexandrescu, Walter Bright, and a loose knit of groupies (including yours truly) and NWCPP guests such as prominent Advanced Windows Debugging author Dan Pravat went to a local watering hole to discuss the future of the D Programming language and shoot the breeze over a pint. Cheers!

CC... Clippings

"All these features make C++ an ideal language for writing operating systems." -- Bartosz Milewski, on SafeD
"C++ is a horrible language. It’s made more horrible by the fact that a lot
of substandard programmers use it, to the point where it’s much much
easier to generate total and utter crap with it. Quite frankly, even if
the choice of C were to do *nothing* but keep the C++ programmers out,
that in itself would be a huge reason to use C." -- Linus Torvalds
According to Time Magazine's latest edition, Linus Torvalds is officially a hero! Linus is cited in the "Rebels & Leaders" category along with Nelson Mandela, Margaret Thatcher, Mikhail Gorbachev and others. In the article 60 Years of Heroes, Linus Torvlads was selected one of the heroes of the past 60 years -- Softpedia
"Heroes become imbued with virtues we wish on them" -- James Burke, American Connections
"As usual, this being a 1.3.x release, I haven't even compiled this kernel yet. So if it works, you should be doubly impressed." -- Linus Torvalds, announcing kernel 1.3.3 on the linux-kernel mailing list.
"Whereas most people find programming in C++ a chore, most Objective-C programmers find the language to be a joy." -- Steve Jobs and the History of Cocoa

Friday, March 21, 2008

Mostly For Fun

The past weekend I worked on setting up the e-commerce bits for my ZeroBUGS Linux debugger.

While the commercial build is compiled with optimizations turned on, and has some extra UI goodies, the beta builds are still available for free.

I was doing some marketing research and I came across an interview bit where the main, revolving question was "What's so special about your product that big system vendors do not offer?"

The person being interviewed went on and on trying to explain the great virtues of his company's software, but missed the simple answer: there are classes of products where a small ISV has a much better chance to come up with good software than a large corporation.

Take my example of a debugger for the C++ language. Unlike a browser or an OS, it is designed for a relatively small yet highly specialized niche. It is not a mass consumer product; it will never be a household name. Its users are few, but extremely picky (since they are very sophisticated software developers themselves). This spells: low margin. Not what a large corporation would bet its resources on.

A big company may however assign a team to slapping something together quickly, most likely to bundle it with another product (such as a compiler) so that they can check a box in a feature list; or maybe just give it away "for free" so that they can sell you their pricey consulting services.

It is rather the kind of product a geek would do primarily just for fun, and only secondarily to make money (so that he can eat, buy more hardware, and do more of the same).

And that's why in the long run the geek's code is better.

Saturday, March 08, 2008

D Compiler Released as DEB Package

Walter Bright and his collaborators released a new version of the Digital Mars D Compiler: http://www.digitalmars.com/d/download.html

A DEB package for Ubuntu, generated with the kit that I put together and announced in a previous post is available for download.

Monday, March 03, 2008

Buy New!

I have no idea whether my old buddies at Amazon have a purposeful sense of humor, but at any rate: buying new toilet paper sounds like a good idea, considering the alternatives...

Watch Expressions

This past weekend I added a couple of new features to the ZeroBUGS debugger.

The user can now monitor arbitrary expressions in the "Watch Variables" window (not just variables, as it was the case up until now). For example you can watch for things such as argv[1], or x * y. (Function calls are supported but I would recommend extreme care in using them; calling arbitrary code in the debugged target may yield some rather interesting effects).

Another new feature is the ability to "map" source and library paths. For example, lets assume that you built your code in /home/joe/cool_project but later moved the source code to /home/joe/cool_source. The debug information inside the binary will still point to /home/joe/cool_project. ZeroBUGS allows you to work around this by setting an environment variable like this:

export ZERO_PATH_MAP="/home/joe/cool_project:/home/joe/cool_source;"

When the debugger encounters source file information prefixed by /home/joe/cool_project it will replace it with /home/joe/cool_source.

You may specify an unlimited number of such pairs, separated by a semicolon. I have uploaded new builds for Ubuntu (32 and 64 bit) and Fedora Core 8 (32bit) this morning, and will update the others over the next week or two.

And the total number of code lines has dropped from 142,992 as reported at the end of December, down to:

Total Physical Source Lines of Code (SLOC) = 139,824
Development Effort Estimate, Person-Years (Person-Months) = 35.80 (429.61)
(Basic COCOMO model, Person-Months = 2.4 * (KSLOC**1.05))
Schedule Estimate, Years (Months) = 2.09 (25.03)
(Basic COCOMO model, Months = 2.5 * (person-months**0.38))
Estimated Average Number of Developers (Effort/Schedule) = 17.16
Total Estimated Cost to Develop = $ 4,836,180
(average salary = $56,286/year, overhead = 2.40).
SLOCCount, Copyright (C) 2001-2004 David A. Wheeler
SLOCCount is Open Source Software/Free Software, licensed under the GNU GPL.
SLOCCount comes with ABSOLUTELY NO WARRANTY, and you are welcome to
redistribute it under certain conditions as specified by the GNU GPL license;
see the documentation for details.
Please credit this data as "generated using David A. Wheeler's 'SLOCCount'."



The decrease is mainly due to code refactoring and to removal of unsuccessful experimental features.

Thursday, February 28, 2008

Zero G

Wow. It has been quite a while since my last post. In my defense I can claim that I have been hugely busy, both at my day job and with Zero.

I fixed a few crashes (thanks to all of you who took the time to submit bug reports) and added a new layout for organizing the debugger window. The user could choose between a "classic" and a "tabbed" view, now there is a third option that allows local variables and stack traces to be viewed at the same time.

Another cool, new feature consists of displaying a description of the current errno value in a tool-tip (as shown in the screen shot).


When I do not work on software I spend time with my family. And when I manage to escape their love I read science news magazines (or at least that's what they label themselves) just to see how deep the conspiracy runs. What conspiracy? You are kidding, right?

In the last issue of Seed, Will Self and Spencer Wells agree that
"we'll probably fast forward by changing our own DNA"
The human race will leap forward using technology to pick up where evolution left... Wait. Isn't this what Ray Kurzweil was saying all along? That we will transcend our biology?

The ultimate goal of evolution be as it may for God's Debris to put itself back together, I believe that the purpose of spreading "news" like these is to get more people to watch The Sarah Connor Chronicles.

Okay, maybe I am kidding. Or maybe someone sits up there in the control room as we very speak, and fabricates more news on, say Global Warming (be afraid, vewy vewy afraid), or on Emmanuelle finding the G spot! No seriously, what kind of news is this? (Even the New Scientist covered it at length). Sorry to break it to you guys, Emmanuelle found the G spot in the seventies, this is old news.

Oh, oops. Just in: Doctor Emmanuelle is a man.

Monday, February 04, 2008

The New ZeroBUGS Python Console


This is the latest feature that I have been working on: the Python Console, which allows users to interactively script the debugger.

The scripting part is not new, but I always felt that it was largely underutilized. It seems that no matter how cool, a feature that is not obvious to the user is simply wasted. Hopefully this new UI element will remedy the situation.

Saturday, January 26, 2008

Package Generator for the D Compiler

Last week or so Andrei asked me if I can take a look at making a deb file for Walter Bright's D Compiler, since the current distribution format (.zip) is hard to install on Linux.

I have no idea how to make debs, and I have no desire whatsoever to learn, thank you, I would rather spend my time reading the Beer Advocate website. I learned a new phrase, by the way: experienced beer drinker. I think it sounds awesome.

I crafted instead a quick project to generate RPMs for DMD, which then get converted automatically into a deb package via alien (same process I use for ZeroBUGS).

Here it is, enjoy.

Sunday, December 30, 2007

Yet Another New Year's Resolution

Because this is a time of the year when people make resolutions about... ahem... loosing weight, and because I recently read in a blog how various programming languages are inherently bloated, I decided I should write down my opinions on fat code.

In this summer post back in June, I was reporting that the ZeroBUGS project had 135,601 lines of code, out of which 120815 (89.10%) were C++. Tonight, after just finishing a big round of changes, the project totals 142,992 lines of code, 126779 (88.66%) being C++.

So one could argue that my project got inflated by roughly 6k lines of (C++) code. And what do I have to show for six months of fattening up?

Bug fixes notwithstanding: I have ported the code to the PowerPC platform, added support for visualizing wide strings and Qt strings, added a feature that allows debug events to be ignored by thread, and (hot from the oven and about to be released) added support for D programming language's associative arrays. In only six thousand lines of code. Not too bad, but that's just my opinion.

What are in general the factors that cause source code to bloat up?

System Refactoring
Back when I was working for Amazon.com, we had to re-write the ordering system (one of the many Amazon software components, the ordering system was in charge of all the magic that happens from the time you click Proceed To Checkout until your items are shipped). At the time when I joined the team that got tasked with the re-write, we had a subsystem consisting mainly of a few tens (or maybe hundreds?) C functions.

This thing was not very flexible, and was already giving up at the seams whenever new functionality was being requested by the business people. It also had statical dependencies to almost anything else in the system. The decision was to replace it with a middle-tier service, with clean APIs.

My boss at that time (an ex Bell Labs guy) had a good plan:
  • design a set of object-oriented, abstract interfaces;
  • implement them in terms of the legacy C code;
  • then rewrite all client code to use this new C++ API;
  • and finally, once there is no more coupling to the C implementation, change the implementation, one small piece at a time.
And this is what we did, and I think it was a successful project, with a few wrinkles though:
  • the migration effort took a couple of years to complete; meanwhile, the old system co-existed and was being actively changed and maintained;
  • do not forget the people factor: some of the middle-managers (I hear these days they got promoted, accordingly to the Peter Principle) had personal political agendas that caused the project to take longer than necessary

The overall effect was that in fact we had two parallel systems in existence: a legacy one, and the "new" one.

The problem is that by the time you are ready to throw away the legacy system, the new system is already old enough to be called "legacy" itself.

Work on another system designed to replace the "new legacy" may start before the "old legacy" is completely retired. So the company may end up with three or more systems being maintained in parallel (sure, the plan is to eventually phase out the legacy, but that may not happen as soon as we wish). And here is one place where bloat, and its first cousin needless redundancy thrive: when code bases are being unnaturally kept alive. Two systems in parallel, and old one and a replacement, are fine. Three or more systems that are trying to solve the some problem is not a Good Thing. And just in case you did not catch it: needless redundancy is in itself a needlessly redundant association of words.

Supporting multiple platforms
Another reason for code to grow in size is portability. In order to make your code portable, you need abstractions and indirections. I started ZeroBUGS in late 2003, because I wanted to best GDB.

My first debugger prototype was less than three thousand lines of code. I was inadequately enthused: the code was stable as a rock, but that's pretty much all I can say about it. It did not work with multiple threads; it did not load core dumps. The support for STAB was sketchy, support for DWARF was none. There was no expression interpreter. The code was stable as a rock, and that's pretty much all I can say about it. And GUI? What GUI?

It took another four years or so to add all these features. Maybe a third to a half a of this time was spent making said features portable. And I do not even mean across OS-es or CPU architectures. You see, when I started to write the GUI I went with Gtk-1.2 and the corresponding C++ wrapper, Gtk--. By the time I was done the world had already moved to Gtk-2.x, and the Gtkmm C++ wrapper was a standard package in most distributions. I had to write an adaptation layer, not unlike the ordering system adaptation API back at Amazon. And that bloated my source code. But today I can compile against Gtkmm or Gtk-1.2 (and 95% of the details are transparent to my client GUI code).

But Gtk-1.2 may no longer be relevant, some people may say. And I think they are right. But let's look at Professor Tanenbaum's MINIX for a second, shall we? Not only because it is a lean and robust system (easy when you do not have features, multi-threading anyone?) but because if you read the source code you notice a strange thing: there are a lot of macros dedicated to ensuring compatibility with Kernighan & Ritchie C compilers. In the 2006 3rd edition of the book. What the heck?

I guess that the lesson here is that writing for portability is fine, but keep an eye on things that may become obsolete sooner than you think. The code that deals with one particular OS, compiler, etc, will then turn into dead weight.

So my 2008 resolution is to get ZeroBUGS on the treadmill.
Happy New Year!

Sunday, November 25, 2007

ZeroBUGS on PowerPC


Happy Thanksgiving! (Yes, we do celebrate Thanksgiving in Seattle in spite of what the Liberal Turkeys want you to believe).

And what a great long weekend this was. We took advantage of the great weather and hiked in the Lincoln and Discovery Parks and walked around Alki Beach, with our son in the backpack.

I have been looking for a solid block of free time from my daytime job in order to look into porting ZeroBUGS to the PowerPC.

I have an old PowerMac that I bought used from a company in Oregon this past summer, for this specific purpose (and promptly installed Ubuntu on it).

But I did not have the time to look into it seriously until now. The main motivation was to see how far I can push the envelope, with the existing design holding up. In other words, I wanted to see how portable my overall design of ZeroBUGS was. And porting prompts one to revisit, re-test and refactor old code.

Of course, I did not expect the outcome of three or four nights of hacking to be perfect.

But the result, while very rough, is quite usable (at least usable enough for me to bootstrap the debugging of the debugger with itself) and I am quite happy with it.

So what's so hard about porting the debugger to the Power architecture? you may ask. Shouldn't it be quite a straightforward task, given it is written in portable C++?

A debugger interacts with the target program (and the OS) at a low level, and hence parts of it depend on the low-level architecture details. Take stack unwinding for example. The layout of stack frames (or links, in PPC parlance) is different than on the Intel chips. And so is the mapping of DWARF register numbers onto the CPU general purpose registers.

Linux runs on PowerPC in big endian mode (as opposed to Intel chips which are little-endian systems) and thus the binary representation of C and C++ bit fields differs.

The hardware support for debugging (special debug CPU registers) also varies across processors.

Well-thought abstractions should isolate these idiosyncrasies. I found out that I have done a good job designing the stack unwinding mechanism (a "driver", template method that delegates to platform-specific bits) but totally blew the model for hardware debug registers.

Oh well. Back to the drawing board. Luckily it is not a heavily-used feature...