From 8be83b1ae0ab0425f4bced86a671fed3eb2ed2a2 Mon Sep 17 00:00:00 2001
From: Jean-Paul Chaput <Jean-Paul.Chaput@lip6.fr>
Date: Tue, 16 Nov 2010 13:43:34 +0000
Subject: [PATCH]   * ./hurricane/src/hurricane:     - New: Backtrace to print
 the stack when an exception is thrown.     - New: In Error, support for
 Backtrack.     - Change: In TextTranslator, provides a default HTML
 translator instead of         building it every time it was needed.     -
 Bug: In Common, when demangling a C++ symbol fails, returns the empty        
 string instead of NULL.

  * ./hurricane/src/viewer:
    - New: In Exception, support for the Backtrack new feature.

  * ./hurricane/src/isobar:
    - Change: In PyHurricane, when catching a C++ exception, adds a newline to
        have a more clean display.
---
 hurricane/src/hurricane/Backtrace.cpp         | 120 ++++++++++++++++++
 hurricane/src/hurricane/CMakeLists.txt        |   4 +-
 hurricane/src/hurricane/Commons.cpp           |   3 +-
 hurricane/src/hurricane/Error.cpp             |  46 ++++---
 hurricane/src/hurricane/Exception.cpp         |  37 +-----
 hurricane/src/hurricane/TextTranslator.cpp    |  29 +++++
 hurricane/src/hurricane/hurricane/Backtrace.h |  77 +++++++++++
 hurricane/src/hurricane/hurricane/Error.h     |  48 +++----
 .../src/hurricane/hurricane/TextTranslator.h  |   8 +-
 hurricane/src/isobar/CMakeLists.txt           |   2 +-
 .../src/isobar/hurricane/isobar/PyHurricane.h |   6 +-
 hurricane/src/viewer/ExceptionWidget.cpp      |  41 +++++-
 hurricane/src/viewer/HApplication.cpp         |  12 +-
 .../viewer/hurricane/viewer/ExceptionWidget.h |   4 +
 hurricane/tests/CMakeLists.txt                |   2 +-
 15 files changed, 345 insertions(+), 94 deletions(-)
 create mode 100644 hurricane/src/hurricane/Backtrace.cpp
 create mode 100644 hurricane/src/hurricane/hurricane/Backtrace.h

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
+//                                     <http://www.gnu.org/licenses/>.
+//
+// ===================================================================
+//
+// $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  <execinfo.h>
+#include  <sstream>
+#include  <iomanip>
+#include  <boost/regex.hpp>
+#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<depth ; ++i ) {
+      if ( boost::regex_search(symbols[i],match,re) ) {
+        string function  ( match[2].first, match[2].second );
+        string demangled ( demangle(function.c_str()) );
+        if ( demangled.empty() )
+          _stack.push_back ( (demangled.empty()) ? function : demangled );
+        else {
+          string reformated ( match[1].first, match[1].second );
+          reformated += "( <b>" + demangled + "</b> )";
+          _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 << "<tt>[" << setw(2) << setfill('0') << depth << "] " << _stack[depth] << "</tt><br>";
+
+    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  <cstdarg>
-
-# include  "hurricane/Error.h"
+#include  <execinfo.h>
+#include  <cstdarg>
+#include  <iomanip>
+#include  <boost/regex.hpp>
+#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 ( "<br>"     , "\n" );
-    translator.addTranslation ( "<em>"     , ""   );
-    translator.addTranslation ( "</em>"    , ""   );
-    translator.addTranslation ( "<strong>" , ""   );
-    translator.addTranslation ( "</strong>", ""   );
-    translator.addTranslation ( "<tt>"     , ""   );
-    translator.addTranslation ( "</tt>"    , ""   );
-    translator.addTranslation ( "<b>"      , ""   );
-    translator.addTranslation ( "</b>"     , ""   );
-    translator.addTranslation ( "<i>"      , ""   );
-    translator.addTranslation ( "</i>"     , ""   );
-    translator.addTranslation ( "<big>"    , ""   );
-    translator.addTranslation ( "</big>"   , ""   );
-    translator.addTranslation ( "<small>"  , ""   );
-    translator.addTranslation ( "</small>" , ""   );
-    translator.addTranslation ( "&lt;"     , "<"  );
-    translator.addTranslation ( "&gt;"     , ">"  );
-
-    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 ( "<br>"     , "\n" );
+      _toTextTranslator.addTranslation ( "<em>"     , ""   );
+      _toTextTranslator.addTranslation ( "</em>"    , ""   );
+      _toTextTranslator.addTranslation ( "<strong>" , ""   );
+      _toTextTranslator.addTranslation ( "</strong>", ""   );
+      _toTextTranslator.addTranslation ( "<tt>"     , ""   );
+      _toTextTranslator.addTranslation ( "</tt>"    , ""   );
+      _toTextTranslator.addTranslation ( "<b>"      , ""   );
+      _toTextTranslator.addTranslation ( "</b>"     , ""   );
+      _toTextTranslator.addTranslation ( "<i>"      , ""   );
+      _toTextTranslator.addTranslation ( "</i>"     , ""   );
+      _toTextTranslator.addTranslation ( "<big>"    , ""   );
+      _toTextTranslator.addTranslation ( "</big>"   , ""   );
+      _toTextTranslator.addTranslation ( "<small>"  , ""   );
+      _toTextTranslator.addTranslation ( "</small>" , ""   );
+      _toTextTranslator.addTranslation ( "&lt;"     , "<"  );
+      _toTextTranslator.addTranslation ( "&gt;"     , ">"  );
+    }
+
+    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
+//                                     <http://www.gnu.org/licenses/>.
+//
+// ===================================================================
+//
+// $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  <string>
+#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<std::string>  _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 "<Backtrace>"; }
+  
+
+} // 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<Translation>  _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<char*>(getString(w).c_str()) );  \
+      std::string message = "\n" + getString(w);                 \
+      PyErr_Warn ( HurricaneWarning, const_cast<char*>(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  <QCloseEvent>
 #include  <QLabel>
 #include  <QPushButton>
+#include  <QCheckBox>
 #include  <QHBoxLayout>
 #include  <QVBoxLayout>
 #include  <QFrame>
@@ -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       ( "<b>Oups! I did it again!</b>" );
 
+    _trace->setTextFormat ( Qt::RichText );
+    _trace->setText       ( "<b>No program trace sets yet.</b>" );
+    _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  <csignal>
 #include  <iostream>
+#include  <iomanip>
 
-#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} )