Question

I recently spent a fairly substantial amount of time tracking down a problem that turned out to be caused by compiling a library with -D_GLIBCXX_DEBUG (which tells libstdc++ to use a debug version of the standard library with extra checks) but compiling the client program without. This caused an ABI compatibility problem.

Is there some way I can automatically detect problems like this with GCC? Visual Studio provides the detect_mismatch pragma which I think would have served this purpose, but I'm unaware of any GCC equivalent. GCC does something with embedding a symbol name (e.g. GLIBCXX_3.4.9), and I can imagine schemes that would cause a linking error because of an undefined symbol if a corresponding symbol (e.g. mylib_debug_stl) were not present, but the only ways I can think of to get a use of that symbol are really hacky.

Alternatively, how do other people avoid this issue? Build the checked version of the library to a different name or something like that?

Was it helpful?

Solution

Is there some way I can automatically detect problems like this with GCC?

Only the linker can detect if you link incompatible code, not the compiler.

The alternative linker, gold, can detect some problems with the --detect-odr-violations option.

Alternatively, how do other people avoid this issue? Build the checked version of the library to a different name or something like that?

I just ensure I rebuild everything when I want to use the Debug Mode, I don't think I've ever wanted to keep a library around that was built with Debug Mode. It's meant for debugging, not for normal use.

I rarely use -D_GLIBCXX_DEBUG anyway, I more often do something like:

#if 0
# include <debug/vector>
namespace my_class_stl = __gnu_debug;
#else
#include <vector>
namespace my_class_stl = std;
#endif

struct my_class
{
  typedef my_class_stl::vector<int> container;
  typedef container::iterator iterator;
  // ...
};

Then I change the preprocessor condition when I want to use a Debug Mode vector for that specific class, without affecting every container in the program. Because the change involves writing to the file (and so updating its timestamp) anything that depends on that header will get rebuilt by make, and there are two distinct types, std::vector<int> and __gnu_debug::vector<int>, which have different symbols and can't be confused by the linker.

Just defining _GLIBCXX_DEBUG doesn't cause all dependencies to be rebuilt, and silently alters the definition of std::vector globally, rather than changing specific containers to a different type with a different name, __gnu_debug::vector

OTHER TIPS

turned out to be caused by compiling a library with -D_GLIBCXX_DEBUG (which tells libstdc++ to use a debug version of the standard library with extra checks) but compiling the client program without.

It is an explicit libsdc++ debugging mode design goal to support such configuration, and I somewhat doubt that that was the actual cause of your problem.

The problem may have disappeared after you rebuilt the library without -D_GLIBCXX_DEBUG, but that doesn't prove that the ABI incompatibility was the root cause.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top