In Backtrace, prevent looping when an error occur inside itself.

* Bug: In Hurricane, in Backtrace, under RHEL 6 when the package
    <devtoolset-2-binutils-devel> is *not* installed, Backtrace uses the
    wrong "bfd.h" from the system instead of the one from the devtoolset2,
    causing itself to core.
      The Backtrace, then try to create a second Backtrace from this
    error, generating an infinite loop. To prevent this situation add a
    counter so that only one Backtrace can be created at a any time.
    And incidentally display a more meaningful error message along with
This commit is contained in:
Jean-Paul Chaput 2016-08-09 11:49:55 +02:00
parent 30b636ffb8
commit 675e20867b
2 changed files with 22 additions and 4 deletions

View File

@ -262,7 +262,6 @@ namespace {
return; return;
} }
} }
} }
} }
@ -414,6 +413,7 @@ namespace Hurricane {
// Class : "Hurricane::Backtrace". // Class : "Hurricane::Backtrace".
int Backtrace::_callCount = 0;
TextTranslator Backtrace::_textTranslator = TextTranslator::toTextTranslator(); TextTranslator Backtrace::_textTranslator = TextTranslator::toTextTranslator();
const size_t Backtrace::_stackSize = 50; const size_t Backtrace::_stackSize = 50;
@ -428,6 +428,18 @@ namespace Hurricane {
Backtrace::Backtrace () Backtrace::Backtrace ()
: _stack() : _stack()
{ {
if (_callCount > 0) {
_stack.push_back( "[BUG] Backtrace::Backtrace(): An error occurred in the backtace *istself*." );
_stack.push_back( "" );
_stack.push_back( " Under RHEL 6, this may be due to a link with a wrong version of <libbfd>," );
_stack.push_back( " please check that you have the <devtoolset-2-binutils-devel> package" );
_stack.push_back( " installed." );
_stack.push_back( "" );
_stack.push_back( " For other OSs, check for any problems related to BFD." );
return;
}
++_callCount;
#if (defined __linux__ || defined __FreeBSD__ || defined __APPLE__) #if (defined __linux__ || defined __FreeBSD__ || defined __APPLE__)
void* rawStack [ _stackSize ]; void* rawStack [ _stackSize ];
size_t depth = backtrace ( rawStack, _stackSize ); size_t depth = backtrace ( rawStack, _stackSize );
@ -498,6 +510,10 @@ namespace Hurricane {
} }
Backtrace::~Backtrace ()
{ --_callCount; }
string Backtrace::htmlWhere () const string Backtrace::htmlWhere () const
{ {
ostringstream where; ostringstream where;

View File

@ -43,15 +43,17 @@ namespace Hurricane {
class Backtrace { class Backtrace {
public: public:
Backtrace (); Backtrace ();
~Backtrace ();
inline std::string where () const; inline std::string where () const;
inline std::string textWhere () const; inline std::string textWhere () const;
std::string htmlWhere () const; std::string htmlWhere () const;
inline std::string _getTypeName () const; inline std::string _getTypeName () const;
inline std::string _getString () const; inline std::string _getString () const;
private: private:
static TextTranslator _textTranslator; static int _callCount;
static const size_t _stackSize; static TextTranslator _textTranslator;
std::vector<std::string> _stack; static const size_t _stackSize;
std::vector<std::string> _stack;
}; };