Created
January 7, 2018 11:24
-
-
Save bolry/ca4f90a93ff1066a10b44d9947fa8312 to your computer and use it in GitHub Desktop.
Example use of __cxa_demangle with no memory leaks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Original example from https://gcc.gnu.org/onlinedocs/libstdc++/manual/ext_demangling.html | |
#include <cmath> | |
#include <cstdlib> | |
#include <array> | |
#include <exception> | |
#include <iostream> | |
#include <sstream> | |
#include <stdexcept> | |
#include <cxxabi.h> | |
struct empty { | |
}; | |
template<typename T, int N> | |
struct foobar { | |
}; | |
std::array<char const*, 4> lookup = | |
{{ | |
"The demangling operation succeeded", | |
"A memory allocation failure occurred", | |
"mangled_name is not a valid name under the C++ ABI mangling rules", | |
"One of the arguments is invalid" | |
}}; | |
int main() | |
{ | |
std::size_t sz = 17; | |
char* buffer = static_cast<char*>(std::malloc(sz)); | |
// exception classes not in <stdexcept>, thrown by the implementation | |
// instead of the user | |
int status; | |
std::bad_exception x; | |
std::exception & e = x; | |
char *realname = abi::__cxa_demangle(e.what(), buffer, &sz, &status); | |
if (realname) { | |
std::cout << e.what() << "\t=> `" << realname << "'\t: " << status | |
<< '\n'; | |
buffer = realname; | |
} else { | |
std::cout << "demangle for `" << e.what() << "' failed due to `" | |
<< lookup[std::abs(status)] << "'\n"; | |
} | |
// typeid | |
foobar<empty, 17> u; | |
const std::type_info &ti = typeid(u); | |
realname = abi::__cxa_demangle(ti.name(), buffer, &sz, &status); | |
if (realname) { | |
std::cout << ti.name() << "\t=> `" << realname << "'\t: " << status | |
<< '\n'; | |
buffer = realname; | |
} else { | |
std::cout << "demangle for `" << ti.name() | |
<< "' failed due to `" | |
<< lookup[std::abs(status)] << "'\n"; | |
} | |
std::free(buffer); | |
return 0; | |
} |
https://godbolt.org/z/h6YK91d54
also completely different approach: https://stackoverflow.com/a/56766138
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
std::unique_ptr<char, decltype(free)*> demangle_name(abi::__cxa_demangle(name.c_str(), 0, 0, &status), free);
if(!demangle_name)
...