From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from moutng.kundenserver.de ([212.227.17.10]) by metis.ext.pengutronix.de with esmtp (Exim 4.72) (envelope-from ) id 1SAhV5-0001WD-Qv for ptxdist@pengutronix.de; Thu, 22 Mar 2012 13:52:21 +0100 From: bernhard@bwalle.de Date: Thu, 22 Mar 2012 13:49:02 +0100 Message-Id: <1332420543-27500-1-git-send-email-bernhard@bwalle.de> Subject: [ptxdist] [PATCH 1/2] os: Add execinfo::demangleCxxName() Reply-To: ptxdist@pengutronix.de List-Id: PTXdist Development Mailing List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: ptxdist-bounces@pengutronix.de Errors-To: ptxdist-bounces@pengutronix.de To: ptxdist@pengutronix.de Cc: Bernhard Walle From: Bernhard Walle Signed-off-by: Bernhard Walle --- CMakeLists.txt | 5 ++++ NEWS | 4 +++ csstdxx/CMakeLists.txt | 1 + csstdxx/config.h.in | 2 ++ csstdxx/os.h | 1 + csstdxx/os/execinfo.h | 62 ++++++++++++++++++++++++++++++++++++++++ csstdxx/os/execinfo_common.cpp | 49 +++++++++++++++++++++++++++++++ csstdxx/os/os.doxy | 3 ++ examples/os/CMakeLists.txt | 4 +++ examples/os/c++filt.cpp | 13 +++++++++ tests/test_os.cpp | 19 ++++++++++++ tests/test_os.h | 11 +++++++ 12 files changed, 174 insertions(+) create mode 100644 csstdxx/os/execinfo.h create mode 100644 csstdxx/os/execinfo_common.cpp create mode 100644 examples/os/c++filt.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0aa43eb..63de09d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -159,6 +159,11 @@ unset(CMAKE_REQUIRED_DEFINITIONS) check_symbol_exists(readdir_r "dirent.h" HAVE_READDIR_R) check_symbol_exists(getpwuid_r "pwd.h" HAVE_GETPWUID_R) +include(CheckCXXSymbolExists) +check_include_file_cxx("cxxabi.h" HAVE_CXXABI_H) +if (HAVE_CXXABI_H) + check_cxx_symbol_exists(abi::__cxa_demangle "cxxabi.h" HAVE_ABI_CXA_DEMANGLE) +endif (HAVE_CXXABI_H) include (CheckTypeExistsCXX) diff --git a/NEWS b/NEWS index 440305b..752220a 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +0.5.1 +----- + * os: Add execinfo::demangleCxxName(). + 0.5.0 ----- * concurrent: Add MutexLocker::unlock(). diff --git a/csstdxx/CMakeLists.txt b/csstdxx/CMakeLists.txt index bfd5c57..71af070 100644 --- a/csstdxx/CMakeLists.txt +++ b/csstdxx/CMakeLists.txt @@ -61,6 +61,7 @@ set(CSSTDXX_SRC io/lockfile_common.cpp os/fileutils.cpp + os/execinfo_common.cpp process/atexitexecuter.cpp ) diff --git a/csstdxx/config.h.in b/csstdxx/config.h.in index 0a8304d..ecf135f 100644 --- a/csstdxx/config.h.in +++ b/csstdxx/config.h.in @@ -76,6 +76,8 @@ #cmakedefine HAVE_OPEN64_LFS #cmakedefine HAVE_READDIR_R #cmakedefine HAVE_GETPWUID_R +#cmakedefine HAVE_CXXABI_H +#cmakedefine HAVE_ABI_CXA_DEMANGLE #cmakedefine WITH_SERIAL_BUS_ACCESS #cmakedefine HAVE_CLOCK_GETTIME diff --git a/csstdxx/os.h b/csstdxx/os.h index d7ceefe..389c4bb 100644 --- a/csstdxx/os.h +++ b/csstdxx/os.h @@ -14,5 +14,6 @@ #include #include #include +#include #endif /* CSSTDXX_CSSTDXX_OS_H_ */ diff --git a/csstdxx/os/execinfo.h b/csstdxx/os/execinfo.h new file mode 100644 index 0000000..49cc21f --- /dev/null +++ b/csstdxx/os/execinfo.h @@ -0,0 +1,62 @@ +/* + * Copyright (C) Corscience GmbH & Co. KG + * + * Projectname - Redmine:CSstdxx + * Module ID - os + */ + +#ifndef CSSTDXX_OS_EXECINFO_H_ +#define CSSTDXX_OS_EXECINFO_H_ + +#include + +namespace cs { +namespace os { +namespace execinfo { + +/** + * \brief Demangles a C++ identifier + * + * Sometimes C++ identifiers appear with name mangling applied, for example + * in that piece of code, at least on Linux/gcc (the standard doesn't say anything + * about what the type information string should look like): + * + * \code + * #include + * + * struct Vehicle { + * virtual ~Vehicle() {} // the type should have RTTI + * }; + * + * struct Car : public Vehicle {}; + * + * Vehicle *v = new Car; + * std::cout << "v is a " << typeid(*v).name() << std::endl; + * \endcode + * + * On Linux, this prints "3Car" instead of just "Car". While that + * can be decoded simply by looking at the name, there are situations where + * the names are more complex. + * + * On the commandline on Linux you can use c++filt to demangle such names. + * Programmatically there are different compiler-specific APIs to decode them. + * cs::os::execinfo::demangleCxxName() is a wrapper around them. + * + * \note Currently this function is implemented when libstdc++ is used (independent + * of the operating system). Tested with clang and gcc on Linux. + * + * \param[in] name the name that should be demangled + * \param[out] ok if not NULL, then this variable will be set to \c true on success + * or to \c false on failure. + * \return the demangled name on success or \p name on failure. + * \since 0.5.1 + * \ingroup os_execinfo + * \sa http://en.wikipedia.org/wiki/Name_mangling + */ +std::string demangleCxxName(const char *name, bool *ok=NULL); + +} // namespace execinfo +} // namespace os +} // namespace cs + +#endif /* CSSTDXX_OS_EXECINFO_H_ */ diff --git a/csstdxx/os/execinfo_common.cpp b/csstdxx/os/execinfo_common.cpp new file mode 100644 index 0000000..e9bee8a --- /dev/null +++ b/csstdxx/os/execinfo_common.cpp @@ -0,0 +1,49 @@ +/* + * Copyright (C) Corscience GmbH & Co. KG + * + * Projectname - Redmine:CSstdxx + * Module ID - os + */ + +#include +#include +#include "execinfo.h" + +#ifdef HAVE_CXXABI_H +# include +#endif + +namespace cs { +namespace os { +namespace execinfo { + +#if defined(HAVE_ABI_CXA_DEMANGLE) +std::string demangleCxxName(const char *name, bool *ok) +{ + int status; + char* result = abi::__cxa_demangle(name, NULL, 0, &status); + if (result && status == 0) { + if (ok) + *ok = true; + std::string resultString(result); + free(result); + return resultString; + } + else { + if (ok) + *ok = false; + return std::string(name); + } +} +#else +std::string demangleCxxName(const char *name, bool *ok) +{ + if (ok) + *ok = false; + return std::string(); +} +#endif + +} // namespace execinfo +} // namespace os +} // namespace cs diff --git a/csstdxx/os/os.doxy b/csstdxx/os/os.doxy index 4b9838e..57d5336 100644 --- a/csstdxx/os/os.doxy +++ b/csstdxx/os/os.doxy @@ -15,6 +15,9 @@ \defgroup os_process Process utilities \ingroup os +\defgroup os_execinfo Runtime execution information +\ingroup os + */ // vim: set ft=doxygen: diff --git a/examples/os/CMakeLists.txt b/examples/os/CMakeLists.txt index d96de60..e117fb7 100644 --- a/examples/os/CMakeLists.txt +++ b/examples/os/CMakeLists.txt @@ -25,6 +25,10 @@ add_executable(tempfile tempfile.cpp) target_link_libraries(tempfile csstdxx) set(EXAMPLE_PROGRAMS ${EXAMPLE_PROGRAMS} tempfile) +add_executable(c++filt c++filt.cpp) +target_link_libraries(c++filt csstdxx) +set(EXAMPLE_PROGRAMS ${EXAMPLE_PROGRAMS} c++filt) + if (INSTALL_CSSTDXX_EXAMPLES) install(TARGETS ${EXAMPLE_PROGRAMS} DESTINATION bin/csstdxx) endif (INSTALL_CSSTDXX_EXAMPLES) diff --git a/examples/os/c++filt.cpp b/examples/os/c++filt.cpp new file mode 100644 index 0000000..6a36e32 --- /dev/null +++ b/examples/os/c++filt.cpp @@ -0,0 +1,13 @@ +#include +#include + +int main(int argc, char *argv[]) +{ + if (argc != 2) { + std::cerr << "Usage: c++filt " << std::endl; + return -1; + } + + std::cout << cs::os::execinfo::demangleCxxName(argv[1]) << std::endl; + return 0; +} diff --git a/tests/test_os.cpp b/tests/test_os.cpp index 29fa1db..683e875 100644 --- a/tests/test_os.cpp +++ b/tests/test_os.cpp @@ -458,6 +458,25 @@ void TestProcess::testExec() CPPUNIT_ASSERT(execute("bladoesnotexist", StringVector()) != 0); } +// +// TestExecinfo +// + +void TestExecinfo::testCppDemangle() +{ +#ifdef __linux__ + bool ok; + std::string result = execinfo::demangleCxxName("_ZN7QWidget8x11EventEP7_XEvent", &ok); + CPPUNIT_ASSERT(ok); + CPPUNIT_ASSERT_EQUAL(std::string("QWidget::x11Event(_XEvent*)"), result); +#endif + + // that must work on any platform + result = execinfo::demangleCxxName("blablubb", &ok); + CPPUNIT_ASSERT(!ok); + CPPUNIT_ASSERT_EQUAL(std::string("blablubb"), result); +} + } // namespace os } // namespace cs diff --git a/tests/test_os.h b/tests/test_os.h index 24e8984..a95d0a9 100644 --- a/tests/test_os.h +++ b/tests/test_os.h @@ -117,6 +117,17 @@ private: CPPUNIT_TEST_SUITE_END(); }; +class TestExecinfo : public CppUnit::TestFixture +{ +public: + void testCppDemangle(); + +private: + CPPUNIT_TEST_SUITE(TestExecinfo); + CPPUNIT_TEST(testCppDemangle); + CPPUNIT_TEST_SUITE_END(); +}; + } // namespace os } // namespace cs -- 1.7.9.4 -- ptxdist mailing list ptxdist@pengutronix.de