c++g++libstdc++rhel6devtoolset

__cxa_demangle fails on rhel6 (centos6) with devtoolset-4 gcc-5.2


I've made an attempt at the minimal test case. This case passes on rhel-7 with devtoolset-4 (gcc-5.2), and fails under rhel-6. Status -2 indicates "mangled_name is not a valid name under the C++ ABI mangling rules." https://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-html-USERS-4.3/a01696.html

Am I doing it all wrong or is this a bug I'm going to have to work around somehow if I want to use gcc-5.2 on RHEL-6? If so, any recommendations? My best thought so far is to regex "IJ" in the mangled name to "II" before giving it to __cxa_demangle(). If that is likely to be relatively reliable I can live with it.

#include <iostream>
#include <string>
#include <tuple>
#include <typeinfo>
#include <cxxabi.h>

#define DUMP(x) std::cout << #x << " is " << x << std::endl

template<typename T>
void print_type(T t)
{
    int status;
    auto name = typeid(t).name();
    DUMP(name);
    auto thing2 = abi::__cxa_demangle(name, 0, 0, &status);
    if(status == 0)
    {
        DUMP(thing2);
    }
    else
    {
        std::cout << typeid(t).name() << " failed to demangle\n";
        DUMP(status);
    }
}

typedef std::tuple<foo_t, foo_t> b_t;

int main(int argc, char **argv)
{
    std::tuple<bool, bool> t;
    print_type(t);
}

Centos-6 output

name is St5tupleIJbbEE
St5tupleIJbbEE failed to demangle
status is -2

Centos-7 output

name is St5tupleIJbbEE
thing2 is std::tuple<bool, bool>

Centos-6 output with devtoolset-3 (gcc-4.9)

name is St5tupleIIbbEE
thing2 is std::tuple<bool, bool>

Solution

  • std::string typestring(typeid(T).name());
    auto pos = typestring.find("IJ");
    if(pos != std::string::npos)
    {
        // gcc-5.2 uses IJ in typestring where
        // gcc-4.9 used II - this fugly hack makes
        // cxa_demangle work on centos/rhel-6 with gcc-5.2
        // eg std::tuple<bool, bool> 
        typestring[pos + 1] = 'I';
    }
    rv = abi::__cxa_demangle(typestring.c_str(), 0, 0, &status);