walrii
walrii

Reputation: 3522

non-portable way to find exception type in catch (...) for g++

Related questions:

This question differs because I don't care about portability. I'm interested in code specifically for g++ or perhaps even specific versions of g++ (4.6.3). It will not be used in production.

I'm dealing with legacy code that has thousands of throw statements with perhaps hundreds of thrown types. This code runs on nearly 1000 machines and catches about 40 throws per day. It is not repeatable.

At the outside layer, I can do a try { /.../ } catch (...) { /* caught it */ } and see that an exception was thrown. But I have not been able to find the type of the exception, let alone the location it is thrown from.

I believe the information must be available because code like the following works and prints "Y":

#include <iostream>
using namespace std;
struct X {};
struct Y {};
struct Z {};
int main(int, char **) {
    try {
        //...
        throw Y();
        //...
    } catch (...) {
        cout << "Caught unknown" << endl;
        try {
            throw;
        } catch (const X &x) {
            cout << "X" << endl;
        } catch (const Y &y) {
            cout << "Y" << endl;
        } catch (const Z &z) {
            cout << "Z" << endl;
        }
    }
}

Are there any [non-portable|dirty|nasty|ugly]* tricks to identify the exception type under g++ in a catch (...)?

Upvotes: 1

Views: 256

Answers (1)

Robert Fleming
Robert Fleming

Reputation: 1407

Here's what I use:

#include <cxxabi.h>

using std::string;
string deMangle(const char* const name)
{
  int status = -1;
  char* const dem = __cxxabiv1::__cxa_demangle(name, 0, 0, &status);

  const string ret = status == 0 ? dem : name;

  if (status == 0)
    free(dem);

  return ret;
}

string getGenericExceptionInfo()
{
  const std::type_info* t = __cxxabiv1::__cxa_current_exception_type();
  char const* name = t->name();

  return deMangle(name);
}

Usage:

catch (...)
  {
    std::cerr << "caught: " << getGenericExceptionInfo() << std::endl;
  }

Upvotes: 3

Related Questions