Loading...
Searching...
No Matches
Error.cc
//FJSTARTHEADER
// $Id$
//
// Copyright (c) 2005-2021, Matteo Cacciari, Gavin P. Salam and Gregory Soyez
//
//----------------------------------------------------------------------
// This file is part of FastJet.
//
// FastJet is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// The algorithms that underlie FastJet have required considerable
// development. They are described in the original FastJet paper,
// hep-ph/0512210 and in the manual, arXiv:1111.6097. If you use
// FastJet as part of work towards a scientific publication, please
// quote the version you use and include a citation to the manual and
// optionally also to hep-ph/0512210.
//
// FastJet 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 General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with FastJet. If not, see <http://www.gnu.org/licenses/>.
//----------------------------------------------------------------------
//FJENDHEADER
#include "fastjet/Error.hh"
#include "fastjet/config.h"
#include <sstream>
#ifndef __FJCORE__
// printing the stack would need execinfo
#ifdef FASTJET_HAVE_EXECINFO_H
#include <execinfo.h>
#include <cstdlib>
#ifdef FASTJET_HAVE_DEMANGLING_SUPPORT
#include <cstdio>
#include <cxxabi.h>
#endif // FASTJET_HAVE_DEMANGLING_SUPPORT
#endif // FASTJET_HAVE_EXECINFO_H
#endif // __FJCORE__
FASTJET_BEGIN_NAMESPACE // defined in fastjet/internal/base.hh
using namespace std;
#ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
atomic<bool> Error::_print_errors{true};
atomic<bool> Error::_print_backtrace{false};
atomic<ostream *> Error::_default_ostr{& cerr};
atomic<mutex *> Error::_stream_mutex{nullptr};
#else
bool Error::_print_errors = true;
bool Error::_print_backtrace = false;
ostream * Error::_default_ostr = & cerr;
#endif // FASTJET_HAVE_LIMITED_THREAD_SAFETY
#if (!defined(FASTJET_HAVE_EXECINFO_H)) || defined(__FJCORE__)
LimitedWarning Error::_execinfo_undefined;
#endif
//----------------------------------------------------------------------
#ifndef __FJCORE__
// demangling only is included, i.e. --enable-demangling is specified
// at configure time, execinfo.h is present and the GNU C++ ABI is
// supported
#if defined(FASTJET_HAVE_EXECINFO_H) && defined(FASTJET_HAVE_DEMANGLING_SUPPORT)
// demangle a given backtrace symbol
//
// Notes:
// - at the moment, only the symbol is parsed.
// - one can get the offset by using
// "%*[^(]%*[^_]%127[^+)]%64[+x0123456789abcdef]", symbol, offset
// and checking if sscanf returns 0, 1 or 2
// (offset includes the leading +)
// - Similarly one could exctract the address and try to convert it
// into a filename+line number like addr2line does but this seems
// to require exteral dependencies. If we want to go down that
// route, one could look into the inplementation o faddr2line(.c)
// and/or dladdr.
string Error::_demangle(const char* symbol) {
size_t size;
int status;
char temp[128];
char* demangled;
// first, try to demangle a c++ name
// decryption:
// %*[^(] matches any number of characters different from "("
// the * tells not to store in input var
// %*[^_] matches any number of characters different from "_"
// the * tells not to store in input var
// %127[^)+] matches at most 127 characters different from "+"
// match is stored
if (1 == sscanf(symbol, "%*[^(]%*[^_]%127[^)+]", temp)) {
//cout << symbol << " -> " << temp << endl;
if (NULL != (demangled = abi::__cxa_demangle(temp, NULL, &size, &status))) {
string result(demangled);
free(demangled);
return result;
}
}
//if that didn't work, try to get a regular c symbol
if (1 == sscanf(symbol, "%127s", temp)) {
return temp;
}
//if all else fails, just return the symbol
return symbol;
}
#endif // FASTJET_HAVE_DEMANGLING_SUPPORT && FASTJET_HAVE_EXECINFO_H
#endif // __FJCORE__
//----------------------------------------------------------------------
Error::Error(const std::string & message_in) {
_message = message_in;
// Thread-safety note:
// get the ostream once and for all (avoids that another thread
// comes and changes that somewhere in the processing after the
// test
ostream* ostr = _default_ostr;
if (_print_errors && ostr){
ostringstream oss;
oss << "fastjet::Error: "<< message_in << endl;
#ifndef __FJCORE__
// only print the stack if execinfo is available and stack enabled
#ifdef FASTJET_HAVE_EXECINFO_H
if (_print_backtrace){
void * array[10];
char ** messages;
int size = backtrace(array, 10);
messages = backtrace_symbols(array, size);
oss << "stack:" << endl;
for (int i = 1; i < size && messages != NULL; ++i){
#ifdef FASTJET_HAVE_DEMANGLING_SUPPORT
oss << " #" << i << ": " << _demangle(messages[i])
<< " [" << messages[i] << "]" << endl;
#else
oss << " #" << i << ": " << messages[i] << endl;
#endif
}
free(messages);
}
#endif // FASTJET_HAVE_EXECINFO_H
#endif // __FJCORE__
#ifdef FASTJET_HAVE_LIMITED_THREAD_SAFETY
if (_stream_mutex){
std::lock_guard<std::mutex> guard(*_stream_mutex);
*ostr << oss.str();
ostr->flush(); // get something written to file even if the program aborts
} else
#endif // FASTJET_HAVE_LIMITED_THREAD_SAFETY
{
*ostr << oss.str();
ostr->flush(); // get something written to file even if the program aborts
}
}
}
//----------------------------------------------------------------------
void Error::set_print_backtrace(bool enabled) {
#if (!defined(FASTJET_HAVE_EXECINFO_H)) || defined(__FJCORE__)
if (enabled) {
_execinfo_undefined.warn("Error::set_print_backtrace(true) will not work with this build of FastJet");
}
#endif
_print_backtrace = enabled;
}
FASTJET_END_NAMESPACE
fastjet::Error::Error
Error()
default constructors
Definition Error.hh:55
fastjet::Error::set_print_backtrace
static void set_print_backtrace(bool enabled)
controls whether the backtrace is printed out with the error message or not.
Definition Error.cc:171