#1291 Static data duplication and unitialized usage / link failures

Metadata

Property Value
Reported by Steffen Müthing (steffen.muething@iwr.uni-heidelberg.de)
Reported at Apr 29, 2013 19:36
Type Bug Report
Version 2.2
Operating System Unspecified / All
Last edited by Steffen Müthing (steffen.muething@iwr.uni-heidelberg.de)
Last edited at Oct 9, 2013 05:04
Closed by Steffen Müthing (steffen.muething@iwr.uni-heidelberg.de)
Closed at Oct 9, 2013 05:04
Closed in version Unknown
Resolution Fixed
Comment Fixed in dune-common e628beb and dune-geometry 228271c

Description

I have been working around a problem with dune-geometry for the better part of a year now, where my programs would randomly crash somewhere in the reference element setup code.

I always thought that this was a problem limited to my (admittedly rather quirky) OS X setup, but last week Jurgis Pods told me about similar problems he was encountering.

The issue is really technical and I honestly don't completely understand how it is triggered: dune-geometry contains quite a lot of singleton template classes, which are all realized approximately like this:

template class A { A(); public: static const A& instance() { static A a; return a; } };

In every compilation unit that contains a call to A::instance(), the compiler instantiates the method and generates a weak symbol (as well as weak symbols for the static variable a and its guard variable). Those weak symbols are later merged by the linker to satisfy the ODR requirements of C++. That part is easy enough. Unfortunately, this doesn't work when multiple libraries contain definitions of instance(), as the compiler will sometimes fail to correctly deduce the symbol type of instance(), a or its guard variable. In some cases, they will not be marked as weak, while in other cases they become private (invisible from outside the library), which wreaks havoc and creates a horrible mix of initialized and un-initialized versions of the same static variable within the process (on my machine) or an outright linker failure due to ODR violation (Jurgis).

After some googling I found the following web page about symbol visibility and libraries:

http://gcc.gnu.org/wiki/Visibility

That page recommends explicitly marking exported symbols with attribute((visibility("default"))) or an appropriate wrapper macro. Doing so actually fixes the problem, so I suggest adding DUNE_EXPORT and DUNE_PRIVATE macros to dune-common and annotating the involved methods in dune-geometry (see attached patches).

One patch adds a new header visibility.hh with the required macros to dune-common, the other marks all affected methods in dune-geometry.

Attachments