Commit 8d9b5d3c authored by Sebastien Ponce's avatar Sebastien Ponce
Browse files

In case the compilation takes place in debug mode, add code to extract file,...

In case the compilation takes place in debug mode, add code to extract file, function and line numbers in the backtraces
parent 99c50385
......@@ -33,7 +33,8 @@ IF(DEFINED CMAKE_BUILD_TYPE)
ELSE()
# log choosen default (RelWithDebInfo) and set it
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "Choose the type of build." FORCE)
message (STATUS "Override with -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo")
ENDIF(DEFINED CMAKE_BUILD_TYPE)
......
......@@ -28,6 +28,15 @@
#include <stdlib.h>
#include "Backtrace.hpp"
#ifdef COLLECTEXTRABACKTRACEINFOS
// Forward declaration for extracting more information in the backtraces
namespace castor {
namespace exception {
std::string collectExtraInfos(const std::string &address);
}
}
#endif // COLLECTEXTRABACKTRACEINFOS
castor::exception::Backtrace::Backtrace(): m_trace() {
void * array[200];
g_lock.lock();
......@@ -44,21 +53,27 @@ castor::exception::Backtrace::Backtrace(): m_trace() {
* between a '(' and a +
* line format: /usr/lib/somelib.so.1(_Mangle2Mangle3Ev+0x123) [0x12345] */
if ((std::string::npos != line.find("(")) && (std::string::npos != line.find("+"))) {
std::string before, theFunc, after;
std::string before, theFunc, after, addr;
before = line.substr(0, line.find("(")+1);
theFunc = line.substr(line.find("(")+1, line.find("+") - (line.find("(") + 1));
after = line.substr(line.find("+"), std::string::npos);
theFunc = line.substr(line.find("(")+1, line.find("+")-line.find("(")-1);
after = line.substr(line.find("+"), line.find("[")-line.find("+")+1);
addr = line.substr(line.find("[")+1, line.find("]")-line.find("[")-1);
int status(-1);
char * demangled = abi::__cxa_demangle(theFunc.c_str(), NULL, NULL, &status);
if (0 == status) {
m_trace += before;
m_trace += demangled;
m_trace += after;
m_trace += "\n";
#ifdef COLLECTEXTRABACKTRACEINFOS
m_trace += collectExtraInfos(addr);
#else
m_trace += addr;
#endif // COLLECTEXTRABACKTRACEINFOS
m_trace += "]";
} else {
m_trace += strings[i];
m_trace += "\n";
}
m_trace += "\n";
free(demangled);
} else {
m_trace += strings[i];
......@@ -71,3 +86,73 @@ castor::exception::Backtrace::Backtrace(): m_trace() {
/* Implementation of the singleton lock */
castor::exception::Backtrace::mutex castor::exception::Backtrace::g_lock;
#ifdef COLLECTEXTRABACKTRACEINFOS
/// code dedicated to extracting more information in the backtraces, typically
/// resolving line numbers from adresses
/// This code is compiled only in debug mode (where COLLECTEXTRABACKTRACEINFOS will be defined)
/// as it's pretty heavy
#include <bfd.h>
#include <sstream>
namespace castor {
namespace exception {
/// code dedicated to collecting extra infos on the backtrace (typically line numbers)
/// compiled only in debug mode (where RESOLVELINENUMBERS will be defined)
/// as it's pretty heavy
static bfd* s_abfd = 0;
static asymbol **s_syms = 0;
static asection *s_text = 0;
static pthread_mutex_t s_mutex;
static bool s_mutex_is_initialized = false;
std::string collectExtraInfos(const std::string &address) {
std::ostringstream result;
// if mutex not yet initilize, initialize it
if (!s_mutex_is_initialized) {
pthread_mutex_init(&s_mutex, NULL);
s_mutex_is_initialized = true;
}
pthread_mutex_lock(&s_mutex);
// if debug symbols were not yet analyzed, let's do it
if (!s_abfd) {
char ename[1024];
int l = readlink("/proc/self/exe",ename,sizeof(ename));
if (l != -1) {
ename[l] = 0;
bfd_init();
s_abfd = bfd_openr(ename, 0);
if (s_abfd) {
/* oddly, this is required for it to work... */
bfd_check_format(s_abfd,bfd_object);
unsigned storage_needed = bfd_get_symtab_upper_bound(s_abfd);
s_syms = (asymbol **) malloc(storage_needed);
bfd_canonicalize_symtab(s_abfd, s_syms);
s_text = bfd_get_section_by_name(s_abfd, ".text");
}
}
}
if (s_abfd && s_text && s_syms) {
std::stringstream ss;
long offset;
ss << std::hex << address;
ss >> offset;
offset -= s_text->vma;
if (offset > 0) {
const char *file;
const char *func;
unsigned line;
if (bfd_find_nearest_line(s_abfd, s_text, s_syms, offset, &file, &func, &line) && file) {
int status(-1);
char * demangledFunc = abi::__cxa_demangle(func, NULL, NULL, &status);
result << "line " << line << " of file " << file
<< " in " << (status?func:demangledFunc) << " (" << address << ")";
}
}
}
pthread_mutex_unlock(&s_mutex);
return result.str();
}
}
}
#endif // COLLECTEXTRABACKTRACEINFOS
......@@ -67,6 +67,10 @@ set (COMMON_LIB_SRC_FILES
../castor/common/CastorConfiguration.cpp)
add_library (castorcommon SHARED ${COMMON_LIB_SRC_FILES})
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set_property(SOURCE ../castor/exception/Backtrace.cpp APPEND PROPERTY COMPILE_FLAGS -DCOLLECTEXTRABACKTRACEINFOS)
endif(CMAKE_BUILD_TYPE STREQUAL "Debug")
target_link_libraries(castorcommon debug bfd)
CastorSetLibraryVersions (castorcommon)
target_link_libraries (castorcommon dl ${UUID_LIB})
install (TARGETS castorcommon DESTINATION ${CASTOR_DEST_LIB_DIR})
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment