« May 2004 | Main | July 2004 »

June 30, 2004

Toronto in the Summer

For my birthday I went to go visit my girl for the weekend. I had been to Toronto a couple of times in the winter, and it's a nice city, but it's cold, and I'm not a fan of said cold. In the Summer, however, it's pretty nice indeed.

Kristen and I walked down College street in search of the right place to eat and meet her friends for a drink. We ended up and yet another yummy Italian restaurant (seems to be a lot of those in Toronto) and on the way, we spotted a place with a sign: "Port Bar". It turns out that I'm a big fan of port wine, and Kristen and I have started sampling port. I'm keeping a little notebook and everything. So this was quite the interesting discovery. After dinner, we all (a few people met us at the restaurant) headed over to the port joint, and it was, as I like to say, pretty damned OK.

I think we're going to have to make a trip up to Napa specifically for port tasting and purchasing sometime soon.

June 09, 2004

Stack Traces in Python Threads

I mentioned before that I'm using XMLRPC to debug a mutli-threaded Python application.

One of the things I'd like to get from this new debugging tool is a stack trace for the various threads my application is running. Sometimes, it appears to get stuck, and I'd like to know what it's doing. A deadlock of some sort is a likely cause, but I would really like to know where that deadlock is happening, and log output is not quite as detailed as I'd like, plus adding more logging just to tell me where I am required frequent restarts, which is a major drag.

It seems, however, that there is no way in Python to get a list of all running threads. Nor can you, from one thread, get a stack trace for another thread. However, in my program, I'm creating a set of worker threads, and I'm keeping track of them already, so I don't have to ask for a list of all of the threads. The trick part is then to get stack traces from these threads. Lacking the ability to inspect another thread directly, I found that Python's tracing utilities, which facilitate the Python debugging and profiling tools, can be used to get that information. Each worker thread calls sys.settrace(self._trace) in its run() method, and implements this tracing method:

def _trace(self, frame, event, arg):
    self._frame = frame
In the main thread, a status() method returns a trace for each thread:
def status(self):
    import inspect

    self._lock.acquire()
    try:
        status = "Available threads:\n"

        for worker in self._available_threads:
            status = status + "  " + worker.getName() + ":\n"

            frame = worker._frame
            if frame:
                status = status + "    stack:\n"
                for frame, filename, line, function_name, context, index in inspect.getouterframes(frame):
                    status = status + "      " + function_name + " @ " + filename + " # " + str(line) + "\n"

            status = status + "\n"

        return status
    finally:
        self._lock.release()

I'm building up a string here because it's a return value that can be sent over XMLRPC and printed. Structured data may be more useful, but hopefully you get the idea. Now I can not only inspect my programs state remotely, but see exactly what it's doing:

[bluntman:~] wsanchez% python
Python 2.3 (#1, Sep 13 2003, 00:49:11) 
[GCC 3.3 20030304 (Apple Computer, Inc. build 1495)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import xmlrpclib
>>> p = xmlrpclib.ServerProxy("http://localhost:8001", allow_none = 1)
>>> p.status()
Available threads:
  thread01:
    stack:
      _release_save@/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/threading.py#181
      wait@/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/threading.py#223
      wait@/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/threading.py#350
      run@/Users/wsanchez/Python/test/Manager.py#20
      __bootstrap@/System/Library/Frameworks/Python.framework/Versions/2.3/lib/python2.3/threading.py#436

One downside to this approach is that we're now incurring a fair bit of overhead because of all of the tracing; every statement the runtime executes now includes invoking the trace method and storing the frame. If performance is a concern, this can be problematic. However, it's easy enough to comment out the sys.settrace() call and uncomment it only when this level of debugging is desired.

June 07, 2004

Tech Reunions 2004

This past weekend I went back to Cambridge for my 10-year M.I.T. class reunion. Kristen met me at Logan and we had a great time.

One of the things once does on reunions is all those touristy things people that live somewhere never get around to doing: we went to the Boston Pops and took a Boston Duck Tour. The Pops were cool until they broke out into Billy Joel, which is a bit lacking in the interesting department, at least without lyrics. That said, having never been, it was good to go. The Duck Tours are entertaining, even though they keep asking everyone to quack at passersby.

Benana provide the best hospitality in the Greater Boston Area.

Boston is an amazing town. My friend Rodney took us for a marvelous lunch at a Spanish restaurant on Newbury Street called Tapeo, then Ben and Ana joined us for an extensive walking tour of Boston, which is nearing completion of the largest public works project in history, specifically an 8-lane freeway that goes under the city, built through landfill with skyscrapers overhead.

The Big Dig is a phenomenal project that, among other things, got rid of a nasty eyesore of an elevated freeway. When you walk past Quincy market, you longer see a green monstrosity; instead: sky. And two blocks past that, Boston Harbor, which I'd never walked to before. The entire waterfront is being revitalized, with parks, a new massive federal court building, hotels, and so on. A metropolis older than the union of several states that ran out of real estate a long time ago has a whole new district. It's mind boggling, and it's not the first time Boston has seen such change (eg. the Back Bay used to be… well, a bay).

Kristen and I finished the day with a trip to Finale for Molten Chocolate and a Flight of Five Ports, which is simply a sublime way to end the day.

The one negative to the trip was travel. Air travel is rarely pleasant, but American Airlines managed to disappoint on a grand scale on all four legs of my trip. I connected through Dallas in both directions. Leaving San Jose, the flight was delayed because the plane didn't arrive from it's last trip on time. Leaving Dallas, we had to wait for an hour and a half in a warm airplane because the flight crew didn't arrive from their last trip on time. Leaving Boston, the flight was delayed because the flight crew was again absent. And finally, leaving Dallas, we had a delay in boarding because the cleaning crew needed more time and then we had to wait in a hot airplane for half an hour while they replaced a part for the air conditioning system, then for another two hours in a warm airplane to wait for the weather that developed while we were waiting for the A/C to get fixed. Does air travel really have to suck that much? Never mind the joy that is buying tickets in the first place.