summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac7
-rw-r--r--lib/common/Utils.cpp148
2 files changed, 89 insertions, 66 deletions
diff --git a/configure.ac b/configure.ac
index 2b591030..4802b139 100644
--- a/configure.ac
+++ b/configure.ac
@@ -152,6 +152,7 @@ else
fi
AC_SEARCH_LIBS([dlsym], ["dl"])
+AC_CHECK_FUNCS([dlsym dladdr])
### Checks for typedefs, structures, and compiler characteristics.
@@ -263,7 +264,7 @@ if test "x$box_cv_have_large_file_support" = "xyes"; then
fi
## Find out how to do file locking
-AC_CHECK_FUNCS([flock])
+AC_CHECK_FUNCS([flock fcntl])
AC_CHECK_DECLS([O_EXLOCK],,, [[#include <fcntl.h>]])
AC_CHECK_DECLS([F_SETLK],,, [[#include <fcntl.h>]])
@@ -399,7 +400,7 @@ cat parcels.txt | sed -e 's/#.*//' | while read cmd subdir configure_args; do
done || exit $?
# Write summary of important info
-cat <<EOC
+cat | tee config.log.features <<EOC
A summary of the build configuration is below. Box Backup will function
without these features, but will work better where they are present. Refer
to the documentation for more information on each feature.
@@ -409,7 +410,7 @@ Large files: $box_cv_have_large_file_support
Berkeley DB: $ax_path_bdb_ok
Readline: $have_libreadline
Extended attributes: $ac_cv_header_sys_xattr_h
-EOC | tee config.log.features
+EOC
### Warnings at end for visibility
diff --git a/lib/common/Utils.cpp b/lib/common/Utils.cpp
index 6f21330d..6afafe84 100644
--- a/lib/common/Utils.cpp
+++ b/lib/common/Utils.cpp
@@ -24,6 +24,10 @@
#include <cxxabi.h>
#endif
+#ifdef HAVE_DLFCN_H
+ #include <dlfcn.h>
+#endif
+
#include "Utils.h"
#include "CommonException.h"
#include "Logging.h"
@@ -73,88 +77,106 @@ void SplitString(const std::string &String, char SplitOn, std::vector<std::strin
}
#ifdef SHOW_BACKTRACE_ON_EXCEPTION
+static std::string demangle(const std::string& mangled_name)
+{
+ #ifdef HAVE_CXXABI_H
+ int status;
+
+#include "MemLeakFindOff.h"
+ char* result = abi::__cxa_demangle(mangled_name.c_str(),
+ NULL, NULL, &status);
+#include "MemLeakFindOn.h"
+
+ if (result == NULL)
+ {
+ if (status == 0)
+ {
+ BOX_WARNING("Demangle failed but no error: " <<
+ mangled_name);
+ }
+ else if (status == -1)
+ {
+ BOX_WARNING("Demangle failed with "
+ "memory allocation error: " <<
+ mangled_name);
+ }
+ else if (status == -2)
+ {
+ // Probably non-C++ name, don't demangle
+ /*
+ BOX_WARNING("Demangle failed with "
+ "with invalid name: " <<
+ mangled_name);
+ */
+ }
+ else if (status == -3)
+ {
+ BOX_WARNING("Demangle failed with "
+ "with invalid argument: " <<
+ mangled_name);
+ }
+ else
+ {
+ BOX_WARNING("Demangle failed with "
+ "with unknown error " << status <<
+ ": " << mangled_name);
+ }
+
+ return std::string(mangled_name);
+ }
+ else
+ {
+ std::string output = result;
+#include "MemLeakFindOff.h"
+ std::free(result);
+#include "MemLeakFindOn.h"
+ return output;
+ }
+ #else // !HAVE_CXXABI_H
+ return mangled_name;
+ #endif // HAVE_CXXABI_H
+}
+
void DumpStackBacktrace()
{
void *array[10];
- size_t size = backtrace (array, 10);
- char **strings = backtrace_symbols (array, size);
-
+ size_t size = backtrace(array, 10);
BOX_TRACE("Obtained " << size << " stack frames.");
for(size_t i = 0; i < size; i++)
{
- // Demangling code copied from
- // cctbx_sources/boost_adaptbx/meta_ext.cpp, BSD license
-
- std::string mangled_frame = strings[i];
- std::string output_frame = strings[i]; // default
-
- #ifdef HAVE_CXXABI_H
- int start = mangled_frame.find('(');
- int end = mangled_frame.find('+', start);
- std::string mangled_func = mangled_frame.substr(start + 1,
- end - start - 1);
+ std::ostringstream output;
+ output << "Stack frame " << i << ": ";
- int status;
-
-#include "MemLeakFindOff.h"
- char* result = abi::__cxa_demangle(mangled_func.c_str(),
- NULL, NULL, &status);
-#include "MemLeakFindOn.h"
+ #ifdef HAVE_DLADDR
+ Dl_info info;
+ int result = dladdr(array[i], &info);
- if (result == NULL)
- {
- if (status == 0)
- {
- BOX_WARNING("Demangle failed but no error: " <<
- mangled_func);
- }
- else if (status == -1)
+ if(result == 0)
{
- BOX_WARNING("Demangle failed with "
- "memory allocation error: " <<
- mangled_func);
+ BOX_LOG_SYS_WARNING("Failed to resolve "
+ "backtrace address " << array[i]);
+ output << "unresolved address " << array[i];
}
- else if (status == -2)
+ else if(info.dli_sname == NULL)
{
- // Probably non-C++ name, don't demangle
- /*
- BOX_WARNING("Demangle failed with "
- "with invalid name: " <<
- mangled_func);
- */
- }
- else if (status == -3)
- {
- BOX_WARNING("Demangle failed with "
- "with invalid argument: " <<
- mangled_func);
+ output << "unknown address " << array[i];
}
else
{
- BOX_WARNING("Demangle failed with "
- "with unknown error " << status <<
- ": " << mangled_func);
+ uint64_t diff = (uint64_t) array[i];
+ diff -= (uint64_t) info.dli_saddr;
+ output << demangle(info.dli_sname) << "+" <<
+ (void *)diff;
}
- }
- else
- {
- output_frame = mangled_frame.substr(0, start + 1) +
- result + mangled_frame.substr(end);
-#include "MemLeakFindOff.h"
- std::free(result);
-#include "MemLeakFindOn.h"
- }
- #endif // HAVE_CXXABI_H
+ #else
+ output << "address " << array[i];
+ #endif // HAVE_DLADDR
- BOX_TRACE("Stack frame " << i << ": " << output_frame);
+ BOX_TRACE(output.str());
}
-
-#include "MemLeakFindOff.h"
- std::free (strings);
-#include "MemLeakFindOn.h"
}
-#endif
+#endif // SHOW_BACKTRACE_ON_EXCEPTION