diff --git a/hurricane/src/hurricane/Backtrace.cpp b/hurricane/src/hurricane/Backtrace.cpp new file mode 100644 index 00000000..c01b98f6 --- /dev/null +++ b/hurricane/src/hurricane/Backtrace.cpp @@ -0,0 +1,120 @@ + +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2010, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Remy Escassut | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Module : "./Error.cpp" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#include +#include +#include +#include +#include "hurricane/Backtrace.h" + + +namespace Hurricane { + + using std::string; + using std::vector; + using std::setw; + using std::setfill; + using std::ostringstream; + + +// ------------------------------------------------------------------- +// Class : "Hurricane::Backtrace". + + + TextTranslator Backtrace::_textTranslator = TextTranslator::toTextTranslator(); + const size_t Backtrace::_stackSize = 50; + + +// Examples of stack symbol string: +// * Linux: +// nwidget(_ZN18SchematicException4initEb+0x47) [0x4515e1] +// * OSX: +// 3 libstdc++.6.dylib 0x9142514b _ZSt9terminatev + 29 + + + Backtrace::Backtrace () + : _stack() + { + void* rawStack [ _stackSize ]; + size_t depth = backtrace ( rawStack, _stackSize ); + char** symbols = backtrace_symbols ( rawStack, depth ); + +#ifdef __linux__ + boost::regex re ( "([^/]+)\\(([^+]+)\\+" ); + boost::cmatch match; + + for ( size_t i=0 ; i )"; + _stack.push_back ( reformated ); + } + } else { + _stack.push_back ( symbols[i] ); + } + } +#else +# ifdef __APPLE__ + boost::regex re ( "(\\d+)\\s+(\\S+)\\s+(\\S+)\\s+(\\S)\\s+\\+\\s+(\\d+)" ); + +# else + _stack.push_back ( "Backtrace only supported under Linux & OSX." ); +# endif +#endif + } + + + string Backtrace::htmlWhere () const + { + ostringstream where; + + for ( size_t depth=0 ; depth<_stack.size() ; ++depth ) + where << "[" << setw(2) << setfill('0') << depth << "] " << _stack[depth] << "
"; + + return where.str(); + } + + +} // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/CMakeLists.txt b/hurricane/src/hurricane/CMakeLists.txt index f6eab7fa..344bf114 100644 --- a/hurricane/src/hurricane/CMakeLists.txt +++ b/hurricane/src/hurricane/CMakeLists.txt @@ -2,6 +2,7 @@ include_directories ( ${HURRICANE_SOURCE_DIR}/src/hurricane ) set ( includes hurricane/Mask.h hurricane/DebugSession.h + hurricane/Backtrace.h hurricane/BasicLayer.h hurricane/BasicLayers.h hurricane/RegularLayer.h hurricane/RegularLayers.h hurricane/ViaLayer.h hurricane/ViaLayers.h @@ -86,6 +87,7 @@ set ( cpps Record.cpp Slot.cpp Commons.cpp + Backtrace.cpp Exception.cpp Bug.cpp Error.cpp @@ -152,6 +154,6 @@ TextTranslator.cpp ) - add_library ( hurricane ${cpps} ) + add_library ( hurricane ${cpps} ${Boost_LIBRARIES} ) install ( TARGETS hurricane DESTINATION lib${LIB_SUFFIX} ) install ( FILES ${includes} DESTINATION include/coriolis2/hurricane ) diff --git a/hurricane/src/hurricane/Commons.cpp b/hurricane/src/hurricane/Commons.cpp index 46d90136..69ba2787 100644 --- a/hurricane/src/hurricane/Commons.cpp +++ b/hurricane/src/hurricane/Commons.cpp @@ -111,7 +111,8 @@ string demangle ( const char* symbol ) char demangled[length]; abi::__cxa_demangle ( symbol, demangled, &length, &status ); - return demangled; + + return (status == 0) ? demangled : ""; } #else diff --git a/hurricane/src/hurricane/Error.cpp b/hurricane/src/hurricane/Error.cpp index bb8f5c70..9a0d51c2 100644 --- a/hurricane/src/hurricane/Error.cpp +++ b/hurricane/src/hurricane/Error.cpp @@ -38,9 +38,11 @@ // x-----------------------------------------------------------------x -# include - -# include "hurricane/Error.h" +#include +#include +#include +#include +#include "hurricane/Error.h" namespace Hurricane { @@ -51,23 +53,26 @@ namespace Hurricane { Error::Error ( const string& reason ) - : Exception() - , _reason(reason) - , _code(0) + : Exception () + , _reason (reason) + , _code (0) + , _backtrace() { } Error::Error ( int code, const string& reason ) - : Exception() - , _reason(reason) - , _code(code) + : Exception () + , _reason (reason) + , _code (code) + , _backtrace() { } Error::Error ( const char* format, ... ) - : Exception() - , _reason() - , _code(0) + : Exception () + , _reason () + , _code (0) + , _backtrace() { static char formatted [ 8192 ]; va_list args; @@ -81,9 +86,10 @@ namespace Hurricane { Error::Error ( int code, const char* format, ... ) - : Exception() - , _reason() - , _code(code) + : Exception () + , _reason () + , _code (code) + , _backtrace() { static char formatted [ 8192 ]; va_list args; @@ -97,11 +103,11 @@ namespace Hurricane { Error::Error ( const Error& error ) - : Exception() - , _reason(error._reason) - , _code(error._code) - { - } + : Exception () + , _reason (error._reason) + , _code (error._code) + , _backtrace(error._backtrace) + { } string Error::_getTypeName () const diff --git a/hurricane/src/hurricane/Exception.cpp b/hurricane/src/hurricane/Exception.cpp index 397701f2..89dd4dec 100644 --- a/hurricane/src/hurricane/Exception.cpp +++ b/hurricane/src/hurricane/Exception.cpp @@ -20,41 +20,6 @@ #include "hurricane/Exception.h" -namespace { - - using namespace Hurricane; - - - TextTranslator getDefaultTextTranslator () - { - TextTranslator translator; - - translator.addTranslation ( "
" , "\n" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "", "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "" , "" ); - translator.addTranslation ( "<" , "<" ); - translator.addTranslation ( ">" , ">" ); - - return translator; - } - - -} // End of anonymous namespace. - - - namespace Hurricane { @@ -63,7 +28,7 @@ namespace Hurricane { // Exception implementation // **************************************************************************************************** -TextTranslator Exception::_textTranslator = getDefaultTextTranslator(); +TextTranslator Exception::_textTranslator = TextTranslator::toTextTranslator(); TextTranslator Exception::_htmlTranslator; diff --git a/hurricane/src/hurricane/TextTranslator.cpp b/hurricane/src/hurricane/TextTranslator.cpp index 00d2f171..701f35a3 100644 --- a/hurricane/src/hurricane/TextTranslator.cpp +++ b/hurricane/src/hurricane/TextTranslator.cpp @@ -33,6 +33,9 @@ namespace Hurricane { using std::vector; using std::cerr; using std::endl; + + + TextTranslator TextTranslator::_toTextTranslator; string TextTranslator::translate ( const string& source ) const @@ -61,4 +64,30 @@ namespace Hurricane { } + const TextTranslator& TextTranslator::toTextTranslator () + { + if ( _toTextTranslator._translations.empty() ) { + _toTextTranslator.addTranslation ( "
" , "\n" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "", "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "" , "" ); + _toTextTranslator.addTranslation ( "<" , "<" ); + _toTextTranslator.addTranslation ( ">" , ">" ); + } + + return _toTextTranslator; + } + + } // End of Hurricane namespace. diff --git a/hurricane/src/hurricane/hurricane/Backtrace.h b/hurricane/src/hurricane/hurricane/Backtrace.h new file mode 100644 index 00000000..8e04e7c2 --- /dev/null +++ b/hurricane/src/hurricane/hurricane/Backtrace.h @@ -0,0 +1,77 @@ + +// -*- C++ -*- +// +// Copyright (c) BULL S.A. 2000-2009, All Rights Reserved +// +// This file is part of Hurricane. +// +// Hurricane is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// Hurricane is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- +// TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Lesser GNU +// General Public License for more details. +// +// You should have received a copy of the Lesser GNU General Public +// License along with Hurricane. If not, see +// . +// +// =================================================================== +// +// $Id$ +// +// x-----------------------------------------------------------------x +// | | +// | H U R R I C A N E | +// | V L S I B a c k e n d D a t a - B a s e | +// | | +// | Author : Jean-Paul Chaput | +// | E-mail : Jean-Paul.Chaput@lip6.fr | +// | =============================================================== | +// | C++ Header : "./hurricane/Backtrace.h" | +// | *************************************************************** | +// | U p d a t e s | +// | | +// x-----------------------------------------------------------------x + + +#ifndef __HURRICANE_BACKTRACE__ +#define __HURRICANE_BACKTRACE__ + +#include +#include "hurricane/Commons.h" +#include "hurricane/TextTranslator.h" + + +namespace Hurricane { + + + class Backtrace { + public: + Backtrace (); + inline std::string where () const; + inline std::string textWhere () const; + std::string htmlWhere () const; + inline std::string _getTypeName () const; + inline std::string _getString () const; + private: + static TextTranslator _textTranslator; + static const size_t _stackSize; + std::vector _stack; + }; + + +// Inline Functions. + inline std::string Backtrace::where () const { return textWhere(); } + inline std::string Backtrace::textWhere () const { return _textTranslator.translate(htmlWhere()); } + inline std::string Backtrace::_getTypeName () const { return "Backtrace"; } + inline std::string Backtrace::_getString () const { return ""; } + + +} // End of Hurricane namespace. + + +#endif diff --git a/hurricane/src/hurricane/hurricane/Error.h b/hurricane/src/hurricane/hurricane/Error.h index 6134ba5f..a14e1500 100644 --- a/hurricane/src/hurricane/hurricane/Error.h +++ b/hurricane/src/hurricane/hurricane/Error.h @@ -38,41 +38,43 @@ // x-----------------------------------------------------------------x -# ifndef __HURRICANE_ERROR__ -# define __HURRICANE_ERROR__ +#ifndef __HURRICANE_ERROR__ +#define __HURRICANE_ERROR__ -# include "hurricane/Exception.h" +#include "hurricane/Exception.h" +#include "hurricane/Backtrace.h" namespace Hurricane { class Error : public Exception { - public: - // Constructors. - Error ( const string& reason ); - Error ( const char* format, ... ); - Error ( int code, const string& reason ); - Error ( int code, const char* format, ... ); - Error ( const Error& error ); - // Methods. - inline string getReason () const; - inline int getCode () const; - // Hurricane Managment. - virtual string _getTypeName () const; - virtual string _getString () const; - + Error ( const string& reason ); + Error ( const char* format, ... ); + Error ( int code, const string& reason ); + Error ( int code, const char* format, ... ); + Error ( const Error& error ); + inline string getReason () const; + inline int getCode () const; + inline string where () const; + inline string textWhere () const; + inline string htmlWhere () const; + virtual string _getTypeName () const; + virtual string _getString () const; private: - // Internal: Attributes. - string _reason; - int _code; + string _reason; + int _code; + Backtrace _backtrace; }; // Inline Functions. - inline string Error::getReason () const { return _reason; } - inline int Error::getCode () const { return _code; } + inline string Error::getReason () const { return _reason; } + inline int Error::getCode () const { return _code; } + inline string Error::where () const { return _backtrace.where(); } + inline string Error::textWhere () const { return _backtrace.textWhere(); } + inline string Error::htmlWhere () const { return _backtrace.htmlWhere(); } } // End of Hurricane namespace. @@ -84,4 +86,4 @@ IOSTREAM_POINTER_SUPPORT(Hurricane::Error); IOSTREAM_VALUE_SUPPORT(Hurricane::Error); -# endif // __HURRICANE_ERROR__ +#endif // __HURRICANE_ERROR__ diff --git a/hurricane/src/hurricane/hurricane/TextTranslator.h b/hurricane/src/hurricane/hurricane/TextTranslator.h index 827c53dc..11adee94 100644 --- a/hurricane/src/hurricane/hurricane/TextTranslator.h +++ b/hurricane/src/hurricane/hurricane/TextTranslator.h @@ -34,9 +34,10 @@ namespace Hurricane { class TextTranslator { public: - inline TextTranslator (); - inline void addTranslation ( const std::string& original, const std::string& translation ); - std::string translate ( const std::string& source ) const; + static const TextTranslator& toTextTranslator (); + inline TextTranslator (); + inline void addTranslation ( const std::string& original, const std::string& translation ); + std::string translate ( const std::string& source ) const; private: class Translation { public: @@ -46,6 +47,7 @@ namespace Hurricane { std::string _translation; }; private: + static TextTranslator _toTextTranslator; std::vector _translations; }; diff --git a/hurricane/src/isobar/CMakeLists.txt b/hurricane/src/isobar/CMakeLists.txt index 916814b6..202e4d3d 100644 --- a/hurricane/src/isobar/CMakeLists.txt +++ b/hurricane/src/isobar/CMakeLists.txt @@ -87,7 +87,7 @@ add_library ( isobar ${sources} ) - target_link_libraries ( isobar hurricane ${PYTHON_LIBRARIES}) + target_link_libraries ( isobar hurricane ${Boost_LIBRARIES} ${PYTHON_LIBRARIES}) add_library ( Hurricane MODULE ${sources} ) set_target_properties ( Hurricane PROPERTIES COMPILE_FLAGS "${COMPILE_FLAGS} -D__PYTHON_MODULE__=1" diff --git a/hurricane/src/isobar/hurricane/isobar/PyHurricane.h b/hurricane/src/isobar/hurricane/isobar/PyHurricane.h index 2539f539..6ed92d7b 100644 --- a/hurricane/src/isobar/hurricane/isobar/PyHurricane.h +++ b/hurricane/src/isobar/hurricane/isobar/PyHurricane.h @@ -848,11 +848,13 @@ extern "C" { # define HCATCH \ } \ catch ( Error& e ) { \ - PyErr_SetString ( HurricaneError, getString(e).c_str() ); \ + std::string message = "\n" + getString(e); \ + PyErr_SetString ( HurricaneError, message.c_str() ); \ return ( NULL ); \ } \ catch ( Warning& w ) { \ - PyErr_Warn ( HurricaneWarning, const_cast(getString(w).c_str()) ); \ + std::string message = "\n" + getString(w); \ + PyErr_Warn ( HurricaneWarning, const_cast(message.c_str()) ); \ } } // End of extern "C". diff --git a/hurricane/src/viewer/ExceptionWidget.cpp b/hurricane/src/viewer/ExceptionWidget.cpp index 1d2fd50f..19121ec0 100644 --- a/hurricane/src/viewer/ExceptionWidget.cpp +++ b/hurricane/src/viewer/ExceptionWidget.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ namespace Hurricane { : QDialog (parent) , _header (new QLabel()) , _message(new QLabel()) + , _trace (new QLabel()) { setAttribute ( Qt::WA_DeleteOnClose ); setModal ( true ); @@ -54,6 +56,14 @@ namespace Hurricane { _message->setTextFormat ( Qt::RichText ); _message->setText ( "Oups! I did it again!" ); + _trace->setTextFormat ( Qt::RichText ); + _trace->setText ( "No program trace sets yet." ); + _trace->hide (); + + QCheckBox* showTrace = new QCheckBox (); + showTrace->setText ( "Show Program Trace" ); + showTrace->setChecked ( false ); + QLabel* ok = new QLabel (); ok->setSizePolicy ( QSizePolicy::Preferred, QSizePolicy::MinimumExpanding ); ok->setPixmap ( QPixmap(":/images/gnome-core.png") ); @@ -68,6 +78,10 @@ namespace Hurricane { contButton->setSizePolicy ( QSizePolicy::Fixed, QSizePolicy::Fixed ); contButton->setText ( tr("Try to Continue") ); + QFrame* separator = new QFrame (); + separator->setFrameShape ( QFrame::HLine ); + separator->setFrameShadow ( QFrame::Sunken ); + QHBoxLayout* hLayout2 = new QHBoxLayout (); hLayout2->addStretch ( 1 ); hLayout2->addWidget ( contButton, Qt::AlignCenter ); @@ -78,10 +92,13 @@ namespace Hurricane { QVBoxLayout* vLayout1 = new QVBoxLayout (); vLayout1->setContentsMargins ( 10, 10, 10, 10 ); vLayout1->setSpacing ( 0 ); - vLayout1->addWidget ( _header , Qt::AlignCenter ); - vLayout1->addWidget ( _message, Qt::AlignCenter ); + vLayout1->addWidget ( _header , Qt::AlignCenter ); + vLayout1->addWidget ( _message , Qt::AlignCenter ); + vLayout1->addWidget ( separator ); + vLayout1->addWidget ( showTrace , Qt::AlignLeft ); + vLayout1->addWidget ( _trace , Qt::AlignCenter ); vLayout1->addSpacing ( 10 ); - vLayout1->addLayout ( hLayout2, Qt::AlignCenter ); + vLayout1->addLayout ( hLayout2 , Qt::AlignCenter ); QHBoxLayout* hLayout1 = new QHBoxLayout (); hLayout1->setSizeConstraint ( QLayout::SetFixedSize ); @@ -91,8 +108,9 @@ namespace Hurricane { setLayout ( hLayout1 ); - connect ( contButton , SIGNAL(clicked()), this, SLOT(accept()) ); - connect ( abortButton, SIGNAL(clicked()), this, SLOT(reject()) ); + connect ( contButton , SIGNAL(clicked()) , this, SLOT(accept()) ); + connect ( abortButton, SIGNAL(clicked()) , this, SLOT(reject()) ); + connect ( showTrace , SIGNAL(stateChanged(int)), this, SLOT(_showTrace(int)) ); } @@ -119,4 +137,17 @@ namespace Hurricane { } + void ExceptionWidget::setTrace ( const QString& where ) + { + _trace->setText ( where ); + } + + + void ExceptionWidget::_showTrace ( int state ) + { + if ( state == Qt::Checked ) _trace->show (); + else _trace->hide (); + } + + } // End of Hurricane Namespace. diff --git a/hurricane/src/viewer/HApplication.cpp b/hurricane/src/viewer/HApplication.cpp index 59e02056..581178e0 100644 --- a/hurricane/src/viewer/HApplication.cpp +++ b/hurricane/src/viewer/HApplication.cpp @@ -25,8 +25,9 @@ #include #include +#include -#include "hurricane/Exception.h" +#include "hurricane/Error.h" #include "hurricane/viewer/Graphics.h" #include "hurricane/viewer/ExceptionWidget.h" #include "hurricane/viewer/HApplication.h" @@ -37,6 +38,8 @@ namespace Hurricane { using std::cerr; using std::endl; + using std::setw; + using std::setfill; using std::exception; @@ -76,6 +79,13 @@ namespace Hurricane { try { return QApplication::notify ( object, event ); } + catch ( Error& e ) { + ExceptionWidget* ew = new ExceptionWidget (); + ew->setMessage ( e.htmlWhat ().c_str() ); + ew->setTrace ( e.htmlWhere().c_str() ); + if ( ew->exec() == QDialog::Rejected ) + kill ( getpid(), SIGSEGV ); + } catch ( Exception& e ) { ExceptionWidget* ew = new ExceptionWidget (); ew->setMessage ( e.htmlWhat().c_str() ); diff --git a/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h b/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h index 3fc6e89e..66126e7c 100644 --- a/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h +++ b/hurricane/src/viewer/hurricane/viewer/ExceptionWidget.h @@ -39,11 +39,15 @@ namespace Hurricane { public: ExceptionWidget ( QWidget* parent=NULL); void setMessage ( const QString& ); + void setTrace ( const QString& ); private: QLabel* _header; QLabel* _message; + QLabel* _trace; protected: virtual void closeEvent ( QCloseEvent* ); + private slots: + void _showTrace ( int state ); }; diff --git a/hurricane/tests/CMakeLists.txt b/hurricane/tests/CMakeLists.txt index d05f63d9..a134e623 100644 --- a/hurricane/tests/CMakeLists.txt +++ b/hurricane/tests/CMakeLists.txt @@ -1,4 +1,4 @@ include_directories ( ${HURRICANE_SOURCE_DIR}/src/hurricane ) add_executable ( htest HTest.cpp ) - target_link_libraries ( htest hurricane ) + target_link_libraries ( htest hurricane ${Boost_LIBRARIES} )