Archive for October, 2007

saving exceptions

Saturday, October 27th, 2007

My previous post explained the need to provide debugging context with C++ exception objects and provided an easy way to manually incorporate arbitrary pieces of context. An interesting suggestion is to incorporate a stack trace into the exception. This time, I’ll look at exceptions in a multi-threaded environment.

Termination style exceptions trace back to the notion of the “undefined” symbol in abstract functional programming. Any expression containing the undefined symbol evaluates to the undefined symbol. In C++, an “expression” is meticulously assembled on the stack. A throw statement is tantamount to dropping the undefined symbol into the expression embodied by the stack. Instead of simply reducing to a single symbol, the throw statement maps to a new expression (beginning with the catch statement) through the following steps:

  1. squirrels away an arbitrary piece of state, pushing it onto the exception stack,
  2. abandons the partially evaluated expression embodied by the current call stack,
  3. and then evaluates a sequence of catch handlers.

Real applications are multi-threaded. Even if side effects are successfully managed in our C++ code, the program-is-an-expression model is not adequate anymore. We have to consider how an exception in one thread should relate to the execution of the other threads of the system.

Many multi-threaded scenarios can be mapped onto the “futures pattern”. A primary thread initiates an asynchronous action and retains the option to retrieve a result at a later time, through a proxy object that represents a “future” value. In this scenario, the correct behavior is obviously that an exception be transfered from the asynchronous actor back to the primary thread when it attempts to retrieve the actual “future value”.

Thus, we want a mechanism to transfer and continue the cancellation action of an exception from an asynchronous actor to a primary thread. This transfer is passive, meaning there is a phase after the exception passes out of the asynchronous actor and before it enters the primary thread. (It is interesting to note that Haskell has an active “throwTotransfer mechanism where a perpetrator thread can asynchronously inject an exception into a victim thread.)

Now - back to C++’s state squirreling. Our exception is held just outside the reach of the “catch” statement. We can only see the slice of it that corresponds to the catch declaration. This presents a bit of a problem when we try to implement something that transfers the exception between threads. The “re-throw” feature lets us transfer the hidden exception state between catch handlers within a thread. However, there is no mechanism that can either completely reveal the hidden state or transfer it to a second thread.

C++09 will solve this problem by adding a handful of functions to retrieve and manipulate an opaque pointer (exception_ptr) to a thrown exception.

Of course, we need this to work in 2007. The simplest approximation of the exception_ptr system is to add a “cloneable_exception” base class with “clone” and “rethrow” virtual functions. However, this approach does not address exceptions thrown from 3rd party libraries. It builds in a kind of obscolescene, since the cloneable_exception base class will be unnecessary once we move to C++09.

Anthony Williams has provided an implementation of exception_ptr for MSVC based on lower-level details of structured exception handling.

I have prototyped a portable implementation, available here. My system requires that all exception types be registered (this is automatic for exceptions thrown using boost::throw_exception). The implementation still needs mutual exclusion protection for access to the exception type registry and reference counts. It effectively adds an “external clone” function to all registered exception types.

easy exceptions

Saturday, October 20th, 2007

C++ exceptions are a distraction. They foil the debugger and they diffuse our attention from the predominant control flow of the software. At point where we throw these exceptions, we usually don’t have enough context to distinguish static programming bugs from dynamic errors. Since our tools aren’t quite as handy with relating exceptions to the underlying programming bugs, the exception seems to get in the way of the debugging effort. We can only see a slice of the exception object. The (Microsoft) debugger is inconsistent about where it breaks when an exception is thrown (for caught versus uncaught exception).

Last week, another developer and I spent a total of four developer-hours hunting down a problem. A couple of exceptions were being thrown. As it turns out, I had mistyped a directory name, which caused boost::filesystem to emit an error in my graphics thread. This in turn caused some collateral damage to a communication process in a different thread - perhaps a timeout due to some interference from the debugger. The debugger tripped on the communication thread before the filesystem error. We noticed the exception, but the filename did not appear in the “what” text of the filesystem error. So, the code-review concentrated on the more complicated communication thread first, wasting a lot of time. If only the filesystem library could have noted the filename in the “what” text, then we could have avoided the extra work.

This little wrong-turn led me to look for a better way of organizing exceptions. C++ exceptions protect our routines from violating their postconditions. They give a routine the chance to “give up” - to surrender the responsibility of coping with a particular input. Of course, for the developer, exceptions are a relatively poor debugging tool. The problem is that they only carry a small fraction of the information that the debugger would be able to provide. Even when the exception carries the appropriate information, it can be difficult to access. For example, my filesystem exception carried a filename field, but the filename did not carry through to the
“what” message. At this early stage of the project, the “what” text is dumped to a debug window, but there are not yet specializations for the many types of exceptions that could wind up falling into my error handler.

An exception object really has two significant responsibilities:

  1. Pass sufficient information about the context of the error back to the exception handler so that it can retry or a useful message can be sent to the user.
  2. Make enough information available to the developer to debug unanticipated exceptions.

We are all used to dealing with the first point. Since arbitrary data can be carried by the exception object, it is easy to meet the requirement. My troublesome filesystem error certainly contained everything that the user needed to know. However, the second point is quite open-ended. We surely do not want to embed a fully featured debugger in our exception handler. On the other hand, it would sure be nice if a whole lot of the context of the exception were carried.

One way to address the issue is to make an exception object that is trivial to add information to, and everything is exposed through the “what” message. For example,

 throw error() << boost::error_info<filename_tag>(path);

There are a couple of problems with the approach. First, the identity of the fields inserted to the stringstream are lost. When my application is all grown up, a filesystem exception will cause a dialog box to open or trigger a search process. In either case, the path in question will need to be interpreted, and extracting it from the human-readable string is going to be annoying.

Second, the stringstream copy constructor and insertion operators can throw bad_alloc. If the copy constructor throws while the exception is being propagated (and not caught before the end of the function), then terminate() will be called. If the insertion operator throws, then the original exception will be lost. David Abrahams warns against embedding std::string objects or formatting before the call to what() for these reasons.

Here is an abbreviation of David Abrahams’s guidelines for exception classes for the boost library:

  1. Derive your exception class from std::exception.
  2. Use virtual inheritance.
  3. Don’t embed a std::string object.
  4. Format the what() message on demand.
  5. Don’t worry too much about the what() message.
  6. Expose relevant information about the cause of the error.
  7. Make your exception class immune to double-destruction.

Items 1 and 2 are addressed with some trivial syntax (make the stringstream a member of a class that inherits from std::exception). It’s worth noting that we are attacking the basis of item 5; in fact our goal is to get enough information in the basic exception object to reduce the need for the debugger. Item 7 can probably be solved using a custom allocator.

Items 3, 4 and 6 are non-trivial to address. There is no built-in way to delay the formatting of an arbitrary list of stream insertion operations. More importantly, there is no easy way to identify fields within the formatted string. The complexity of any attempt to delimit fields in the text string seems to be out of line with the relatively small scale of the problem.

Emil Dotchevski has proposed a library for boost that addresses the basic problem of easily recording arbitrary data fields in an exception object. Here is a before and after example.

Standard exception

 struct error : std::exception {   setFilename(const filesystem::path&);   const filesystem::path& getFilename() const;   const char* what() const; }; void f(boost::filesystem::path path) {   error e;   e.setFilename(path);   throw e; }

With Dotchesvski’s boost Exception proposal:

 struct filename_tag : error_info_value {}; struct error : boost::exception {}; void f(boost::filesystem::path path) {   throw error() << boost::error_info<filename_tag>(path); }

The library is successful at eliminating boilerplate implementation of what and getters/setters. It is well suited to situations where errors can be complex. For example, OpenGL can report a vector of error flags, and there is even the possibility of a flag having multiplicity greater than one. While it is possible to build this field into the type of the exception, it appears to be counterproductive. Microsoft Visual Studio 8 usually describes such a complicated exceptions as having an “unknown type” (although the correct catch clause does get invoked). OpenGL error flags could be easily encoded in the fields of Dotchevski’s library.

Nevertheless, our desire is to make it easy for the library designer to expose the widest variety of details of the context of the error. We expect a wider variety of details to be relevant for debugging than would be required to determine messages for the end-user. While Dotchevski eliminated the boilerplate code that would normally be required for transmitting predefined fields, he does not let the programmer easily add ad-hoc bits of context.

Some people would prefer to use the “what” message as a key to the exception type. The string could serve as a key to a table of user error messages or otherwise provide the fine-grained choice of action. The catch stage of exception filtering is then a more coarse filter. However the typeid operator can be employed for the same purpose, freeing the “what” message for use as a debug stream.

I developed my own exception class to make it as easy as possible to add data to the exception object. The source code is available here. It uses an ostream syntax that can accept any object that is copyable and has a ostream inserter. Here is the basic interface:

 class exception { public:   virtual const char* what() const throw();   void visit(const error_info_visitor_base& v) const;   template void set(const T&t) const;   virtual ~exception() throw(); }; template<typename E, typename F> const E& operator<< (const E& e,const T& t) {   e.set(t);   return e; }

It is the same as std::exception, with the addition of set and visit member functions and an insertion operator. The set member function adds an object to a list of data elements. The visit member function applies a visitor to each data element whose type is compatible with the visitor. To help the error handler get data out of the exception object, there are helper functions for constructing an error_info_visitor class:

 unspecified_type on_error_info(Tag, F f) {   return error_info_field_visitor<error_info&ltTag>,F>(f); } unspecified_type on_error_info(F f) {   return field_visitor<F>(f); }

Here is an example where an exception is thrown, and a data element is added and extracted.

 try {   throw exception() << 5 << "Hello World"; } catch(exception&e) {   using boost::lambda::_1;   using boost::lambda::var;   int i(0);   e.visit(boost::on_error_info<int>(var(i)=_1));   cout << i << "\n"; /*prints "5"*/   cout << e.what() << "\n"; /*prints: "5Hello World"*/ }

At the throw site, the data values are simply recorded. String formatting is not done until the what member function is called.

Often, we need to “translate” exception types in order to better describe the context of the error. My exception class allows the data elements from the first to be inserted into the second exception object. Here is an example:

 class system_error : public boost::exception {   int errno_; public:   explicit system_error(int err=0) : errno_(err) {}   int& err() {return errno_;} }; void f() {   try {     try {       throw boost::exception() << 9 << " hello ";     }     catch(boost::exception&e) {     throw system_error(2) << e;   } } catch(system_error&e) {   using boost::lambda::_1;   using boost::lambda::var;   int i(0);   e.visit(boost::on_error_info&ltint>(var(i)=_1));   cout << i << '\n'; /*prints '9'*/   cout << e.what() << '\n'; /*Prints "9 hello world"*/   cout << e.err() << '\n'; /*Prints '2'*/ }

In the next post, I’ll show how to emulate part of the new C++0x support for “saving exceptions”.

mass moca

Sunday, October 7th, 2007

Julie and I recently visited Mass Moca to see the Spencer Finch exhibit, What time is it on the sun?. Finch’s work strove to reproduce elements of sensory experience removed from their natural context. For example, in “Two Hours, Two Minutes, Two Seconds,” a bank of fans reproduced the variations of the gentle breeze at Walden Pond at a particular time period. In other works, the mood of the museum was altered by the indirect light from pieces that reproduced the light of the sky or the ground at specific locations and times. “Sunlight in an Empty Room” is shown on the right. It reproduces the color of the light in the home of Emily Dickinson as a cloud passes by. The macroscopic context was always obliterated within the piece. However, the exhibition guide recovered the context and its descriptions became an integral part of enjoying the work.

Julie’s first body of work has a similar notion. She visually separates the gestalt of natural objects from particular symmetries, graphic forms or textures.

We found Finch’s “Night Sky…” particularly inspiring. The bulbs hung from the ceiling are connected to describe the molecular structure of pigments that might be used in a painting of the Arizona sky on a particular evening. Finch’s meta-metaphor is fun, but I’m content just to put some interesting lights on our ceiling. The plan is to cover a meandering patch of our eat-in kitchen with light bulbs.

I decided that a relatively dense packing of G40 and G25 bulbs, would look nice. Finch used bulbs with curly filaments, but I’m not sure where to get them. The bulbs will hang by their wires from hardboard panels. Tubular white appliance wire would probably look better than the clear/copper wire that I used. I found the porcelain sockets that Finch used at Home Depot, and Julie used hot-glue to make a kind of strain-relief so that the weight of the bulb is supported by the casing of the wire, rather than the electrical connections (in retrospect, hot glue is probably a poor choice of material to use around a hot bulb).

Each panel is 16×20″ and should hang ten to twenty bulbs. The panels will let me build and install the project in a modular way and hopefully without permanent damage to the ceiling. It’s actually kind of hard to arrange the bulbs “by hand”. They are fragile, and the wires like to tangle and flop around. So I modeled the bulbs and wires in Mathematica and set to work making an energy function whose minimization would give a nice bulb arrangement. The first experiment used ten bulbs. That’s a lot of degrees of freedom, but with some difficulty I managed to coax the built-in numerical minimization engine to give a reasonable arrangement. I will probably need to write my own optimization algorithm to solve a larger number of bulbs. Based on the plan determined by the minimization function, I drilled the holes in the hardboard and used heat-shrink tubing on the wires to the bulbs to set their length. Julie tried replacing the globe-style bulbs with cylindrical ones. It could look interesting (a stubby version of Sina’s “The End of the Red Line” of the Alewife MBTA station), but it would end up being more expensive.

We’ll paint the panel white (better to do this before stringing the wires!), but it looks good. The clear casing on the wire is a bit too stiff; I want the bulbs to hang straight down.