[Pkg-voip-commits] [bctoolbox] 08/57: -add BctbcException class. -Improved stack trace with c++ demangling

daniel at gnoutcheff.name daniel at gnoutcheff.name
Thu Mar 30 04:31:31 UTC 2017


This is an automated email from the git hooks/post-receive script.

gnoutchd-guest pushed a commit to branch debian/sid
in repository bctoolbox.

commit b8685d2633aef97818604ceb3a45b597bb6cec95
Author: Jehan Monnier <jehan.monnier at linphone.org>
Date:   Thu Nov 17 15:30:44 2016 +0100

    -add BctbcException class.
    -Improved stack trace with c++ demangling
---
 include/CMakeLists.txt         |  23 +++++---
 include/bctoolbox/exception.hh |  78 +++++++++++++++++++++++++
 include/bctoolbox/logging.h    |  19 +++---
 src/CMakeLists.txt             |   8 ++-
 src/utils/exception.cc         | 128 +++++++++++++++++++++++++++++++++++++++++
 5 files changed, 236 insertions(+), 20 deletions(-)

diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
index de280ce..79ff0e7 100644
--- a/include/CMakeLists.txt
+++ b/include/CMakeLists.txt
@@ -20,18 +20,25 @@
 #
 ############################################################################
 
-set(BCTOOLBOX_HEADER_FILES
-	bctoolbox/crypto.h
-	bctoolbox/list.h
-	bctoolbox/logging.h
-	bctoolbox/map.h
-	bctoolbox/port.h
-	bctoolbox/vfs.h
+set(HEADER_FILES
+	crypto.h
+	list.h
+	logging.h
+	map.h
+	port.h
+	vfs.h
+	exception.hh
 )
 if(ENABLE_TESTS_COMPONENT)
-	list(APPEND BCTOOLBOX_HEADER_FILES bctoolbox/tester.h)
+	list(APPEND HEADER_FILES tester.h)
 endif()
 
+set(BCTOOLBOX_HEADER_FILES )
+foreach(HEADER_FILE ${HEADER_FILES})
+        list(APPEND BCTOOLBOX_HEADER_FILES "${CMAKE_CURRENT_LIST_DIR}/bctoolbox/${HEADER_FILE}")
+endforeach()
+set(BCTOOLBOX_HEADER_FILES ${BCTOOLBOX_HEADER_FILES} PARENT_SCOPE)
+
 install(FILES ${BCTOOLBOX_HEADER_FILES}
 	DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/bctoolbox
 	PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
diff --git a/include/bctoolbox/exception.hh b/include/bctoolbox/exception.hh
new file mode 100644
index 0000000..ed7f1f3
--- /dev/null
+++ b/include/bctoolbox/exception.hh
@@ -0,0 +1,78 @@
+/*
+	bctoolbox
+	Copyright (C) 2016  Belledonne Communications SARL.
+ 
+	This program is free software: you can redistribute it and/or modify
+	it under the terms of the GNU Affero General Public License as
+	published by the Free Software Foundation, either version 3 of the
+	License, or (at your option) any later version.
+ 
+	This program is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+	GNU Affero General Public License for more details.
+ 
+	You should have received a copy of the GNU Affero General Public License
+	along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef exception_h
+#define exception_h
+
+#include <exception>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <ostream>
+
+
+using namespace std;
+  /**
+  * @brief General pupose exception saving backtrace.
+  *
+  * sample of use:
+  * try {
+  *		throw BCTBX_EXCEPTION << "Hello, this is my exception";
+  * } catch (BctbxException e&) {
+  *    BCTOOLBOX_SLOGD("mylogdomain") << "Exception cauth"<< e;
+  * }
+  *
+  *
+  */
+class BctbxException : public exception {
+public:
+	BctbxException();
+	BctbxException(const string &message);
+	BctbxException(const char *message);
+	virtual ~BctbxException() throw();
+	BctbxException(const BctbxException &other);
+	/**
+	 * print stack strace to stderr
+	 * */
+	void printStackTrace() const;
+	
+	void printStackTrace(std::ostream &os) const;
+	
+	const char *what() const throw();
+	const std::string &str() const;
+	
+	/* same as osstringstream, but as osstream does not have cp contructor, BctbxException can't inherit from
+	 * osstream*/
+	template <typename T2> BctbxException &operator<<(const T2 &val) {
+		mOs << val;
+		return *this;
+	}
+	
+protected:
+	int mOffset; /*to hide last stack traces*/
+private:
+	void *mArray[20];
+	size_t mSize;
+	ostringstream mOs;
+	mutable string mMessage;
+};
+std::ostream &operator<<(std::ostream &__os, const BctbxException &e);
+
+#define BCTBX_EXCEPTION BctbxException() << " " << __FILE__ << ":" << __LINE__ << " "
+
+#endif /* exception_h */
diff --git a/include/bctoolbox/logging.h b/include/bctoolbox/logging.h
index 67660d0..ac3dfc8 100644
--- a/include/bctoolbox/logging.h
+++ b/include/bctoolbox/logging.h
@@ -213,25 +213,24 @@ namespace bctoolbox {
 struct pumpstream : public std::ostringstream {
 	const std::string mDomain;
 	const BctbxLogLevel level;
-	pumpstream(std::string domain, BctbxLogLevel l) : mDomain(domain), level(l) {
-	}
+	pumpstream(std::string domain, BctbxLogLevel l) : mDomain(domain), level(l) {}
 	
 	~pumpstream() {
-		bctbx_log(mDomain.c_str(), level, "%s", str().c_str());
+		bctbx_log(mDomain.empty()?NULL:mDomain.c_str(), level, "%s", str().c_str());
 	}
 };
 
-//#if (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
-//template <typename _Tp> inline pumpstream &operator<<(pumpstream &&__os, const _Tp &__x) {
-//	(static_cast<std::ostringstream &>(__os)) << __x;
-//	return __os;
-//}
-//#endif
+#if (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
+template <typename _Tp> inline pumpstream &operator<<(pumpstream &&__os, const _Tp &__x) {
+	(static_cast<std::ostringstream &>(__os)) << __x;
+	return __os;
+}
+#endif
 
 #define BCTBX_SLOG(domain, thelevel) \
 \
 if (bctbx_log_level_enabled((domain), (thelevel))) \
-	pumpstream((domain),(thelevel))
+		pumpstream((domain?domain:""),(thelevel))
 
 #define BCTBX_SLOGD(DOMAIN) BCTBX_SLOG(DOMAIN, BCTBX_LOG_DEBUG)
 #define BCTBX_SLOGI(DOMAIN) BCTBX_SLOG((DOMAIN), (BCTBX_LOG_MESSAGE))
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e002a35..613209e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -24,8 +24,12 @@ set(BCTOOLBOX_C_SOURCE_FILES
 	containers/list.c
 	logging/logging.c
 	utils/port.c
+	utils/exception.cc
 	vfs.c
 )
+
+set_source_files_properties(utils/exception.cc PROPERTIES COMPILE_FLAGS -std=c++11)
+
 set(BCTOOLBOX_CXX_SOURCE_FILES containers/map.cc)
 
 if(MBEDTLS_FOUND)
@@ -50,7 +54,7 @@ apply_compile_flags(BCTOOLBOX_C_TESTER_SOURCE_FILES_C "CPP" "C")
 apply_compile_flags(BCTOOLBOX_CXX_SOURCE_FILES_C "CPP" "CXX")
 
 if(ENABLE_STATIC)
-	add_library(bctoolbox-static STATIC ${BCTOOLBOX_SOURCE_FILES})
+	add_library(bctoolbox-static STATIC ${BCTOOLBOX_SOURCE_FILES} ${BCTOOLBOX_HEADER_FILES})
 	target_link_libraries(bctoolbox-static ${CMAKE_THREAD_LIBS_INIT})
 	if(WIN32)
 		target_compile_definitions(bctoolbox-static PUBLIC "-DBCTBX_STATIC")
@@ -69,7 +73,7 @@ if(ENABLE_STATIC)
 	endif()
 endif()
 if(ENABLE_SHARED)
-	add_library(bctoolbox SHARED ${BCTOOLBOX_SOURCE_FILES})
+	add_library(bctoolbox SHARED ${BCTOOLBOX_SOURCE_FILES} ${BCTOOLBOX_HEADER_FILES})
 	target_link_libraries(bctoolbox PRIVATE ${CMAKE_THREAD_LIBS_INIT})
 	if(WIN32)
 		target_link_libraries(bctoolbox PRIVATE "Winmm" "Ws2_32")
diff --git a/src/utils/exception.cc b/src/utils/exception.cc
new file mode 100644
index 0000000..4b66ba5
--- /dev/null
+++ b/src/utils/exception.cc
@@ -0,0 +1,128 @@
+/*
+ Flexisip, a flexible SIP proxy server with media capabilities.
+ Copyright (C) 2010-2015  Belledonne Communications SARL, All rights reserved.
+ 
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as
+ published by the Free Software Foundation, either version 3 of the
+ License, or (at your option) any later version.
+ 
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ GNU Affero General Public License for more details.
+ 
+ You should have received a copy of the GNU Affero General Public License
+ along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "bctoolbox/exception.hh"
+#include <execinfo.h>
+#include <unistd.h>
+#include "bctoolbox/logging.h"
+#include "dlfcn.h"
+#include <cxxabi.h>
+#include <iomanip>
+#include <libgen.h>
+
+static void uncaught_handler() {
+	std::exception_ptr p = current_exception();
+	try {
+		rethrow_exception(p);
+	} catch (BctbxException &e) {
+		BCTBX_SLOGE(NULL) << e;
+	} catch (std::exception &ee) {
+		BCTBX_SLOGE(NULL) << "Unexpected exception [" << ee.what() << " ] use BctbxException for better debug";
+	}
+	abort();
+}
+
+BctbxException e;
+
+BctbxException::BctbxException(const char *message) : mOffset(1), mSize(0) {
+	mSize = backtrace(mArray, sizeof(mArray) / sizeof(void *));
+	if (message)
+		mOs << message;
+#if __clang
+	if (get_terminate() != uncaught_handler)
+#endif
+		set_terminate(uncaught_handler); // invoke in case of uncautch exception for this thread
+}
+
+BctbxException::BctbxException(const BctbxException &other) : mOffset(other.mOffset), mSize(other.mSize) {
+	memcpy(mArray, other.mArray, sizeof(mArray));
+	mOs << other.str();
+}
+
+#if __cplusplus > 199711L
+BctbxException::BctbxException(const string &msg) : BctbxException(msg.c_str()) {
+	mOffset++;
+}
+#else
+BctbxException::BctbxException(const string &message) : mOffset(2) {
+	mSize = backtrace(mArray, sizeof(mArray) / sizeof(void *));
+	*this << message;
+	set_terminate(uncaught_handler); // invoke in case of uncautch exception for this thread
+}
+#endif
+
+BctbxException::~BctbxException() throw() {
+	// nop
+}
+
+#if __cplusplus > 199711L
+BctbxException::BctbxException() : BctbxException("") {
+	mOffset++;
+}
+#else
+BctbxException::BctbxException() : mOffset(2) {
+	mSize = backtrace(mArray, sizeof(mArray) / sizeof(void *));
+	*this << "";
+	set_terminate(uncaught_handler); // invoke in case of uncautch exception for this thread
+}
+#endif
+
+void BctbxException::printStackTrace() const {
+	backtrace_symbols_fd(mArray + mOffset, mSize - mOffset, STDERR_FILENO);
+}
+
+void BctbxException::printStackTrace(std::ostream &os) const {
+	char **bt = backtrace_symbols(mArray, mSize);
+	int position=0;
+	for (unsigned int i = mOffset; i < mSize; ++i) {
+		Dl_info info;
+		char *demangled = NULL;
+		int status = -1;
+		if (dladdr(mArray[i], &info) && info.dli_sname) {
+		demangled = abi::__cxa_demangle(info.dli_sname, NULL, 0, &status);
+		
+			os << position++ << setw(20) << basename((char*)info.dli_fname) << setw(16) << info.dli_saddr ;
+			os << " ";
+			if (demangled) {
+				os << demangled;
+				free(demangled);
+			}
+			else
+				os << info.dli_sname;
+			
+		} else {
+			os << bt[i];
+		}
+		os << std::endl;
+	}
+	delete (bt);
+}
+
+const std::string &BctbxException::str() const {
+	mMessage = mOs.str(); // avoid returning a reference to temporary
+	return mMessage;
+}
+const char *BctbxException::what() const throw() {
+	return str().c_str();
+}
+
+// Class BctbxException
+std::ostream &operator<<(std::ostream &__os, const BctbxException &e) {
+	__os << e.str() << std::endl;
+	e.printStackTrace(__os);
+	return __os;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/bctoolbox.git



More information about the Pkg-voip-commits mailing list