Boost.Foreach and Compiler Bugs

Posted on 06 August 2013  •  Permalink  •  Category c++

Boost is a library that definitively boosts your productivity writing C++ code. For instance, for loops can be made a lot more readable if you use Boost.Foreach. It’s almost as if you are writing Python, Objective-C or even Java, which support a foreach construct natively.

However, like always, hiding things behind an abstraction can be a problem. Especially when the abstraction depends on a compiler bug. That’s the case with BOOST_FOREACH in Boost versions prior to Boost 1.47, which relies on a compiler bug for rvalue detection. And it so happens that is compiler bug is fixed in GCC 4.6, which breaks older Boost versions.

Ubuntu 12.04 actually ships with Boost 1.46.1 and GCC 4.6.3. A deadly combination as it seems. Just try to run this little C++ program:

#include <boost/shared_ptr.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <iostream>

const std::vector<boost::shared_ptr<int> > f()
{
  return std::vector<boost::shared_ptr<int> >(4,
    boost::shared_ptr<int>(new int(12)));
}

int main(int argc, char **argv)
{
  BOOST_FOREACH(const boost::shared_ptr<int> &pi, f())
  {
    std::cout << *pi << std::endl;
  }
}

You would expect to see 4 lines printed with the number 12. Instead you will get this:

$ g++ test.cpp -o test
$ ./test
test: /usr/include/boost/smart_ptr/shared_ptr.hpp:412:
  boost::shared_ptr<T>::reference boost::shared_ptr<T>::operator*() const
  [with T = int, boost::shared_ptr<T>::reference = int&]:
    Assertion `px != 0' failed.
Aborted (core dumped)

So what’s actually happening here? Internally Boost.Foreach will try to detect whether the container expression is an lvalue or an rvalue. In the example above the result from f() is such rvalue: a temporary object that will be gone as soon as it goes out of scope. Boost.Foreach takes precautions for that by copying the rvalue internally such that it will live as long as the scope of the for loop.

Now what happens if rvalue detection fails in above example? It means that the vector returned by f() will be gone before the statements in the loop get executed. The destruction of the vector means the smart pointers are destructed too. As a result, trying to access them in the std::cout statement will trigger the px != 0 assertion.

Fortunately this problem is fixed in Boost 1.47 and up. For more information on how Boost.Foreach works, see Conditional Love: FOREACH Redux.

SCons, SWIG & Python

Posted on 27 August 2010  •  Permalink  •  Category c++

There are some problems that you can only really solve, let alone understand, by diving into code. Lucky enough the Open Source movement has spread like wildfire these days, also for developer tools. So besides that it’s fun and very educating to read someone else’s source code, in come cases it’s also really, really helpful to find out how a program is doing its tricks internally to really understand how to best use it. In particular this problem case that I’ve been investigating including a combination of SCons, SWIG and Python.

It’s a pretty straightforward setup. You’ve got this C++ library which you want to export to Python. You’ve already setup an interface to Lua, using SWIG. Now the cool thing about SWIG [1] is, that it’s really easy to export the same interface to different scripting languages, so you want to use SWIG’s power to use your existing setup and extend that from Lua to Python as well. You take your existing .i file, divide it up into two separate files, a general one and a Lua specific one. Say common.i and lua.i where you include common.i in lua.i. Then you can create your new python.i with the Python specific instructions for SWIG, again including common.i. Problem solved.

Well, not if you’re using SCons as your build tool and you put the %module statement in common.i. That does work for Lua, but for Python strange things will happen with SCons’ build dependencies on the .py wrapper file generated by SWIG. I had to go all the way into SCons’ Tool/swig.py to find out what the problem was. While SCons scans for %module statements, which, if found SCons uses to define the .py file build dependencies for Python extensions, %include statements aren’t honored as such. That’s when I undestood that the problem was my Python specific python.i which didn’t have a %module statement! I put that into common.i, reusing it for Lua and Python, thinking that would be ok. However, that setup will mislead SCons to thinking that there are no %module statements at all. So build dependencies will be incorrect, leading to build errors.

Lesson learned: when using SCons, always put the %module statements for SWIG in the .i file that is used to directly generate the scripting language extension from.

[1]Yes I am a fan.

Exceptional Exception Handling

Posted on 21 August 2009  •  Permalink  •  Category c++

Warning: this post is going to be technical; I’ll be using terms like C++, Python, SWIG, static and dynamic linking, shared objects, position independent code, and linux loader, so you can still bail out if all that sounds like gobbledygook to you. If not, well, I’ve been digging into a problem caused by a combination of all the previously mentioned terms. I’ll explain by example, so you can safely try this at home.

Simple Start

We’ll start by creating a C++ library. A very simple one; one function, throwing an exception derived from a generic library exception class. As follows:

// lib.cpp

#include "lib.h"
#include "exceptions.h"

void throwDerivedException()
{
  throw DerivedException();
}

Its header file is a one-liner:

// lib.h

extern void throwDerivedException();

And the exception definitions are inside a single header file:

// exceptions.h

class LibraryException: public std::exception {};
class DerivedException: public LibraryException {};

So that’s that. As I’m a big fan of testing, I’ll create a unit test for my newly created library. We’re focusing on a single problem here, so I’ll just create the necessary tests to trigger the problem I’m investigating. The problem is in the exception handling part, so I’ll create a simple test to make sure that exceptions thrown by throwDerivedException() can actually be caught. More specific, I want to check if my library generic LibraryException can be used to catch unforeseen errors inside my library functions. This obviously is trivial:

// test.cpp

#include "lib.h"
#include "exceptions.h"

int main(int argc, const char *argv[])
{
  // Exception handling check with statically compiled in symbols.
  std::cout << "Testing exceptions, statically linked: ";

  try {
    throwDerivedException();
  }
  catch (LibraryException &e)
  {
    std::cout << "ok\n";
  }
}

Compiling and running the above code will give results as expected:

$ g++ -c lib.cpp
$ g++ -c test.cpp
$ g++ -o test test.o lib.cpp
$ ./testTesting
exceptions, statically linked: ok

So far for C++ and statical linking, that leaves us still with a lot of remaining terms: Python, SWIG, dynamic linking, shared objects, position independent code, and linux loader. I’ll start using more of them very soon, so let’s continue.

Adding Complexity

A common way of supplying access to a library’s interface, besides its native (in our case C++) interface, is providing extensions for script languages. One of the best tools I’ve ever used to do that generically is SWIG. With SWIG you can generate wrapper code to create an interface that you can compile, together with your C++ code, as a shared library that can be dynamically loaded by a script language. In today’s example I’m going to connect my library interface from lib.h to Python. One particular interesting feature of SWIG is its language independent exception handling functionality. I’m going to use that to catch all exceptions that can be thrown by my library interface, identified by LibraryException.

I won’t go into all of SWIG’s details here, you can browse through its excellent online documentation that can be found on http://www.swig.org. I’ll just list the contents of my interface file here:

%module lib
%{
  #include "lib.h"
  #include "exceptions.h"
%}

/* Generic language independent exception handler. */
%include "exception.i"
%exception {
  try {
    $action
  }
  catch (LibraryException &e) {
    SWIG_exception(SWIG_RuntimeError, e.what());
  }
}

%include "lib.h"

Running SWIG on this interface file will generate a so called interface wrapper file, that contains the actual wrapper code to bind the C++ interface to a Python callable interface. In there the $action placeholder will be translated to a call to throwDerivedException() function for the respective Python wrapper function. In turn, a Python understandable RuntimeError will be raised.

All this is best illustrated with a simple Python test script to test the exception functionality, like we did for the C++ interface above:

# test.py
print "Testing exceptions, dynamically loaded with Python:",

# Import SWIG created library.
import lib

try:
  lib.throwDerivedException()
except RuntimeError:
  print "ok"

Compiling and running the above test gives results as expected:

$ swig -c++ -python -o lib_wrap.cpp lib.i
$ g++ -fPIC -c lib.cpp
$ g++ -fPIC -c -I/usr/include/python2.5 lib_wrap.cpp
$ g++ -fPIC -shared -o _lib.so lib_wrap.o lib.o
$ python test.py
Testing exceptions, dynamically loaded with Python: ok

Note that I now pass the -fPIC flag to gcc to emit position-independent code, suitable for dynamic linking.

So Where’s the Problem?

Everything fine so far, however, I’d like to combine both tests into one test executable, since running multiple tests manually is too cumbersome for me. Luckily there’s a function in the Python/C API called PyRun_SimpleFile to execute a Python script from within a C or C++ program. Including Python.h, linking with libpython, and calling Py_Initialize() is all there is to it. Let’s extend the C++ test program:

// test.cpp

#include "lib.h"
#include "exceptions.h"
#include "Python.h"

int main(int argc, const char *argv[])
{
  // Exception handling check with statically compiled in symbols.
  std::cout << "Testing exceptions, statically linked: ";

  try  {
    throwDerivedException();
  }
  catch (LibraryException &e) {
    std::cout << "ok\n";
  }

  // Embedded Python interpreter exception handling check -- this
  // will fail if test executable is statically linked.
  Py_Initialize();
  int result = PyRun_SimpleFile(fopen("test.py", "r"), "test.py");
}

For the test to run successfully, we need to add three lines before importing the generated library in the test script, otherwise it won’t be found:

...

# Add current dir to system path, that's where our lib is.
import sys
sys.path.append(".")

# Import SWIG created library.
import lib

...

So let’s compile this and run the test again:

$ swig -c++ -python -o lib_wrap.cpp lib.i
$ g++ -c -fPIC lib.cpp$ g++ -c -fPIC -I/usr/include/python2.5 test.cpp
$ g++ -c -fPIC -I/usr/include/python2.5 lib_wrap.cpp
$ g++ -fPIC -shared -o _lib.so lib_wrap.o lib.o
$ g++ -fPIC -o test test.o lib.o -lpython2.5
$ ./test
Testing exceptions, statically linked: ok
Testing exceptions, dynamically loaded with dlopen with Python:
terminate called after throwing an instance of 'DerivedException'
  what():  std::exception
Aborted

That’s not what we’d expected. The exception thrown inside the library is not caught by the exception handler code installed by SWIG. How could that happen?

The Problem Explained

After stripping down the actual problem into the simple test example as described, spending a few intense hours in a Googling-reading-Googling-reading loop, and interrogating a compiler guru colleague [1], I could conclude that I found an incarnation of the problem of RTTI crossing shared library boundaries. It’s actually a combination of how gcc does comparisons on the type of C++ objects and how symbols in dynamically shared libraries are resolved.

The entry “dynamic_cast, throw, typeid don’t work with shared libraries” in the GNU GCC FAQ explains the first half of the problem:

The new C++ ABI in the GCC 3.0 series uses address comparisons, rather than string compares, to determine type equality.

But also it describes the root cause of the other half of the problem:

Like other objects that have to be present in the final executable, these std::type_info objects have what is called vague linkage because they are not tightly bound to any one particular translation unit (object file). The compiler has to emit them in any translation unit that requires their presence, and then rely on the linking and loading process to make sure that only one of them is active in the final executable. With static linking all of these symbols are resolved at link time, but with dynamic linking, further resolution occurs at load time. You have to ensure that objects within a shared library are resolved against objects in the executable and other shared libraries.

So what happens in our example? First, the executable is read by the loader, including the exception symbols LibraryException and DerivedException. The C++ interface test is executed, giving the expected results. The Python test will be run, with the embedded Python interpreter. While interpreting the Python test script, the _lib.so library will be loaded. At load time of the library the types inside catch statements are resolved using the symbols in memory of the test executable. In the execution path the throwDerivedException() function will be called. At that moment, at run time, the exception instance types will be resolved, using the local symbols of the library. The exception object that is thrown will have a pointer pointing to the address of the LibraryException type inside the library memory space, while the catch statement inside the wrapper code will check using the address of the LibraryException type from inside the test executable memory space: they won’t match. Hence the exception won’t be caught; program execution aborts.

If you don’t believe me, you can see for yourself. Here’s a link to an archive containing the sample code as discussed. It contains a Makefile too, so just type:

$ make
$ ./test

And there you go. By means of the included Makefile, the archive also contains the three different solutions which I’ll discuss next.

It’s All in the Options

Sometimes a problem that seems to be very complicated in the first place — taking a significant investigation to get to the bottom of it — can have a relatively simple solution. In this particular situation we even have three trivial solutions. As if we have won the lottery.

What we need to do is somehow to instruct the compiler, the linker, or the loader to use the right symbols to resolve the exception types. In other words, we need to make sure that resolving the exception types is not being messed up by either the linker or the loader. We can accomplish that by:

  1. Using shared libraries — if we compile lib.cpp as a shared library say liblib.so, the test executable will not contain exception type symbols. The exception symbols inside liblib.so will remain local and while _lib.so is loaded by Python the exception symbols in there will be resolved locally too.
  2. Exporting symbols to the dynamic symbol table — by exporting all symbols from the test executable to the dynamic symbol table, not only the type of the exception in the catch statement, but also the type of the exception in the throw statement will be resolved inside the executable memory space. The GNU linker has a special option for this purpose: -E, which, according to the GNU ld manual, “when creating a dynamically linked executable, add[s] all symbols to the dynamic symbol table. The dynamic symbol table is the set of symbols which are visible from dynamic objects at run time. If you do not use this option, the dynamic symbol table will normally contain only those symbols which are referenced by some dynamic object mentioned in the link. If you use dlopen to load a dynamic object which needs to refer back to the symbols defined by the program, rather than some other dynamic object, then you will probably need to use this option when linking the program itself.”
  3. Binding references to global symbols to the definition within the shared library — using the -Bsymbolic option from the GNU linker. If we link the _lib.so Python extension with this option, the exception type inside the catch statement will be resolved already to the local symbols inside the library by the linker at link time. When the library is loaded dynamically by Python in the test run, no symbols will be overridden with symbols from the test executable. I chose this third solution as my solution of choice, because it solves the problem inside the Python extension library. As a result, the Python extension becomes fully self contained, which in the particular case I was working on was exactly what I wanted.

These solutions can be tried out using the archive as linked before. The Makefile has, besides the test target, three additional targets:

$ make test_shared
$ make test_export
$ make test_symbolic

that build a differently linked test executable, according to the above described solutions.

Enough compiler-and-linker-fun for me for this week…

[1]A colleague who worked on the Watcom and Microsoft C++ compilers.

Floating Point Trickyness (2) —- select Is’t Broken, Is It?

Posted on 14 May 2009  •  Permalink  •  Category c++

In my previous post I talked about rounding errors with floating point numbers. If you work with real numbers and computers, sooner or later, just like others before you, you will conclude that computers suck at math.

But what if you have a compiler that sucks at math? I recently experienced that that can give you severe headaches. Consider the following code snipplet:

#include <cmath>

int main(int argc, char **argv)
{
  double x = std::sqrt(1.0 - std::pow(2.0, 2));
}

Taking the square root from -3, should be NaN, and if you try this with a recent version of g++, you will get NaN. Everything fine. However, if you try this with g++ 3.4.3 on Sparc, with -O2 turned on, the answer is, well, actually, there is no answer. At least not after 12 hours; our test that includes the same formula as in the above code snipplet ran for more than 12 hours without terminating. That’s how I found this problem. From an infinitely looping test.

It took a while to figure out what was going on since the original problem line was of course bigger including several more mathematical expressions. After breaking it down I could isolate the problem to the simplified expression as shown above.

Even in the strangest cases, usually still “select Isn’t Broken” [1]. But in this (very rare) case it is.

[1]“It is rare to find a bug in the OS or the compiler, or even a third-party product or library. The bug is most likely in the application.” —- From the Pragmatic Programmer, one of the most influential programming books I read.

Floating Point Trickyness

Posted on 11 March 2009  •  Permalink  •  Category c++

Interesting: say you have a 100x100 matrix of doubles. Then you put values in each row from -1 to 1, equally spaced, such that all 100 rows for each column i contain the value:

-1 + i * ((1 - -1) / (100 - 1)) == -1 + i * 2/99

Where the columns are numbered from 0 to 99. By definition, the sum of all elements in this matrix should be 0. For integer numbers, this is true. For floating point numbers, this is tricky.

As a natural born hax0r, you should know that there is something called floating point errors. As the entropy of these values isn’t particularly high, operations on them might result in an error that will be large. But I never thought it could be that different. Watch this [1]:

  • Summing all elements individually gives a result of: 3.108624468950438e-15. A large error, this is what we would expect.

However:

  • Taking the sum of an individual row (doesn’t matter which one, of course) results in: 3.108624468950438e-15. The same number as summing all elements individually!
  • Taking the sum of these rows gives: 3.108624468950438e-13. This is what we would expect, 100 times the sum of a row. The funny thing of course, is the fact that this number is a 100 times different from the sum of all elements.
  • Taking the sum of the columns gives: -2.415845301584341e-13. A completely different number than in the previous cases.

This issue surfaced in a debugging session where we were comparing the result of an algorithm written in Matlab and the same algorithm converted to C++. Although I have a copy of “What Every Computer Scientist Should Know About Floating Point Arithmetic”, which tells you that the addition operator + is not necessarily associative for floating point values, I still had to blink a couple of times when I saw the above results for the first time.

Lesson learned: be careful when you take the sum of (a matrix of) floating point numbers as a comparison measure —- or maybe even more general: beware: floating point number calculations ahead.

[1]You can try this at home either with Matlab or C++, also probably other languages or tools will give similar amazingly unexpected results))

Boosting Productivity

Posted on 12 March 2008  •  Permalink  •  Category c++

Lately I have been busy implementing several things using the libraries available under name of Boost. Boost is a free and open source effort, and has a commercial support branch called Boost Consulting that is dedicated to delivering services, training and what they call enterprise releases. I mention Boost Consulting, firstly because that might help to convince your bosses to use Boost at your company, and secondly so I can quote from their site to introduce Boost:

Boost is a development group creating free software libraries suitable for inclusion in the C++ standard. […] Boost libraries cover a wide range of domains, from concurrency to numerics to language interoperability. The Boost libraries, many of which have passed through the C++ standardization process, have become widely known as an industry standard for design and implementation quality, robustness, and reusability.

The reason for us to start using the Boost libraries is the same as why the Boost libraries were initially started. Again, I quote from boost-consulting.com:

[…] Beman Dawes, then chairman of the C++ committee’s library working group, recognized that languages such as Java and Python were growing in popularity precisely because of the ready availability of library components. Some jobs, he argued, were just too hard in C++ — not because of any inherent limitation, but because the right libraries were not available.

Obviously the Boost consultants eat, and also promote their own dogfood, so they conclude:

[…] Boost is much more than a collection of individual experts: a cultural emphasis on collaboration and inquiry creates an environment where synergies evolve and new insights are discovered. I don’t think any of us expected to become quite so reliant on the Boost libraries in our professional development work, but the Boost libraries have proven themselves to be remarkably useful, versatile, and well-designed. Ten Boost libraries have already been accepted into the next version of the C++ standard.

It is about six months ago that I installed Boost and started testing it in a prototype project, and it is true, once you start using it, there is no way back anymore. Boost is remarkably useful, versatile and well-designed; all three at the same time.