eliot-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Eliot-dev] eliot configure.in dic/Makefile.am dic/dic_exce...


From: Olivier Teulière
Subject: [Eliot-dev] eliot configure.in dic/Makefile.am dic/dic_exce...
Date: Sun, 17 Oct 2010 21:23:40 +0000

CVSROOT:        /cvsroot/eliot
Module name:    eliot
Changes by:     Olivier Teulière <ipkiss>       10/10/17 21:23:40

Modified files:
        .              : configure.in 
        dic            : Makefile.am dic_exception.cpp dic_exception.h 
        game           : game_exception.cpp game_exception.h 
        qt             : Makefile.am main.cpp 
Added files:
        dic            : base_exception.cpp base_exception.h 
                         stacktrace.cpp stacktrace.h 
        m4             : ax_cxx_gcc_abi_demangle.m4 

Log message:
        Print to stderr the complete stack trace in case of exception or 
segmentation fault.
        This feature will only be activated in debug mode, and if available on 
the platform.
        The symbols will even be demangled if possible (i.e. if compiled with 
g++).

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/eliot/configure.in?cvsroot=eliot&r1=1.47&r2=1.48
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/Makefile.am?cvsroot=eliot&r1=1.23&r2=1.24
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_exception.cpp?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/dic_exception.h?cvsroot=eliot&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/base_exception.cpp?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/base_exception.h?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/stacktrace.cpp?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/dic/stacktrace.h?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game_exception.cpp?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/game/game_exception.h?cvsroot=eliot&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/eliot/m4/ax_cxx_gcc_abi_demangle.m4?cvsroot=eliot&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/Makefile.am?cvsroot=eliot&r1=1.19&r2=1.20
http://cvs.savannah.gnu.org/viewcvs/eliot/qt/main.cpp?cvsroot=eliot&r1=1.7&r2=1.8

Patches:
Index: configure.in
===================================================================
RCS file: /cvsroot/eliot/eliot/configure.in,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -b -r1.47 -r1.48
--- configure.in        14 Oct 2010 11:22:18 -0000      1.47
+++ configure.in        17 Oct 2010 21:23:39 -0000      1.48
@@ -22,6 +22,9 @@
 AC_PROG_RANLIB
 PKG_PROG_PKG_CONFIG
 
+AC_CHECK_HEADERS_ONCE(execinfo.h)
+AX_CXX_GCC_ABI_DEMANGLE
+
 dnl --------------------------------------------------------------
 dnl Checks for compilation flags
 dnl --------------------------------------------------------------

Index: dic/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/Makefile.am,v
retrieving revision 1.23
retrieving revision 1.24
diff -u -b -r1.23 -r1.24
--- dic/Makefile.am     18 Sep 2010 13:07:39 -0000      1.23
+++ dic/Makefile.am     17 Oct 2010 21:23:40 -0000      1.24
@@ -23,6 +23,7 @@
 AM_CPPFLAGS = -DLOCALEDIR=\"$(localedir)\" -I$(top_srcdir) -I../intl 
-I$(top_srcdir)/intl $(INCICONV)
 
 libdic_a_SOURCES = \
+       base_exception.cpp base_exception.h \
        dic_exception.cpp dic_exception.h \
        header.cpp header.h \
        dic_internals.h \
@@ -30,6 +31,7 @@
        dic.cpp dic.h \
        dic_search.cpp \
        encoding.cpp encoding.h \
+       stacktrace.cpp stacktrace.h \
        automaton.cpp automaton.h \
        regexp.cpp regexp.h \
        grammar.cpp grammar.h \

Index: dic/dic_exception.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/dic_exception.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- dic/dic_exception.cpp       31 Aug 2008 11:48:12 -0000      1.3
+++ dic/dic_exception.cpp       17 Oct 2010 21:23:40 -0000      1.4
@@ -1,6 +1,6 @@
 /*****************************************************************************
  * Eliot
- * Copyright (C) 2007 Olivier Teulière
+ * Copyright (C) 2007-2010 Olivier Teulière
  * Authors: Olivier Teulière <ipkiss @@ gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -24,17 +24,11 @@
 
 
 DicException::DicException(const string &iMessage)
-    : m_message(iMessage)
+    : BaseException(iMessage)
 {
 }
 
 
-const char *DicException::what() const throw()
-{
-    return m_message.c_str();
-}
-
-
 InvalidRegexpException::InvalidRegexpException(const string &iMessage)
     : DicException(iMessage)
 {

Index: dic/dic_exception.h
===================================================================
RCS file: /cvsroot/eliot/eliot/dic/dic_exception.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- dic/dic_exception.h 29 Nov 2009 16:01:31 -0000      1.4
+++ dic/dic_exception.h 17 Oct 2010 21:23:40 -0000      1.5
@@ -1,6 +1,6 @@
 /*****************************************************************************
  * Eliot
- * Copyright (C) 2007 Olivier Teulière
+ * Copyright (C) 2007-2010 Olivier Teulière
  * Authors: Olivier Teulière <ipkiss @@ gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -21,24 +21,19 @@
 #ifndef DIC_EXCEPTION_H_
 #define DIC_EXCEPTION_H_
 
-#include <exception>
 #include <string>
+#include "base_exception.h"
 
 
 /**
  * Exception class for the dictionary.
- * It simply inherits from the standard exception and overrides
+ * It simply inherits from the base exception and overrides
  * its what() method.
  */
-class DicException: public std::exception
+class DicException: public BaseException
 {
     public:
         DicException(const std::string &iMessage);
-        ~DicException() throw() {}
-        virtual const char *what() const throw();
-
-    private:
-        std::string m_message;
 };
 
 
@@ -46,7 +41,6 @@
 {
     public:
         InvalidRegexpException(const std::string &iMessage);
-        ~InvalidRegexpException() throw() {}
 };
 
 #endif

Index: game/game_exception.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game_exception.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- game/game_exception.cpp     29 Nov 2009 16:01:32 -0000      1.3
+++ game/game_exception.cpp     17 Oct 2010 21:23:40 -0000      1.4
@@ -1,6 +1,6 @@
 /*****************************************************************************
  * Eliot
- * Copyright (C) 2007 Olivier Teulière
+ * Copyright (C) 2007-2010 Olivier Teulière
  * Authors: Olivier Teulière <ipkiss @@ gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -24,17 +24,11 @@
 
 
 GameException::GameException(const string &iMessage)
-    : m_message(iMessage)
+    : BaseException(iMessage)
 {
 }
 
 
-const char *GameException::what() const throw()
-{
-    return m_message.c_str();
-}
-
-
 EndGameException::EndGameException(const string &iMessage)
     : GameException(iMessage)
 {

Index: game/game_exception.h
===================================================================
RCS file: /cvsroot/eliot/eliot/game/game_exception.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- game/game_exception.h       29 Nov 2009 16:01:32 -0000      1.3
+++ game/game_exception.h       17 Oct 2010 21:23:40 -0000      1.4
@@ -1,6 +1,6 @@
 /*****************************************************************************
  * Eliot
- * Copyright (C) 2007 Olivier Teulière
+ * Copyright (C) 2007-2010 Olivier Teulière
  * Authors: Olivier Teulière <ipkiss @@ gmail.com>
  *
  * This program is free software; you can redistribute it and/or modify
@@ -21,24 +21,19 @@
 #ifndef GAME_EXCEPTION_H_
 #define GAME_EXCEPTION_H_
 
-#include <exception>
 #include <string>
+#include "base_exception.h"
 
 
 /**
  * Exception class for the Game library.
- * It simply inherits from the standard exception and overrides
+ * It simply inherits from the base exception and overrides
  * its what() method.
  */
-class GameException: public std::exception
+class GameException: public BaseException
 {
     public:
         GameException(const std::string &iMessage);
-        ~GameException() throw() {}
-        virtual const char *what() const throw();
-
-    private:
-        std::string m_message;
 };
 
 

Index: qt/Makefile.am
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/Makefile.am,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -b -r1.19 -r1.20
--- qt/Makefile.am      12 Sep 2010 15:27:38 -0000      1.19
+++ qt/Makefile.am      17 Oct 2010 21:23:40 -0000      1.20
@@ -104,6 +104,8 @@
 MOSTLYCLEANFILES = $(nodist_eliot_SOURCES)
 
 eliot_LDADD = ../game/libgame.a ../dic/libdic.a @QT_LIBS@ @LIBINTL@ 
@LIBCONFIG_LIBS@ @ARABICA_LIBS@ @EXPAT_LDFLAGS@
+# Needed for proper stack trace handling
+eliot_LDFLAGS = -rdynamic
 
 # Generate a cpp file from the resources
 resources.cpp: eliot.qrc $(RESOURCES)

Index: qt/main.cpp
===================================================================
RCS file: /cvsroot/eliot/eliot/qt/main.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- qt/main.cpp 12 Feb 2010 18:16:57 -0000      1.7
+++ qt/main.cpp 17 Oct 2010 21:23:40 -0000      1.8
@@ -21,9 +21,13 @@
 #include "config.h"
 
 #include <string>
+#include <exception>
+#include <iostream>
 #include <QApplication>
 #include <QLocale>
 #include <QTranslator>
+#include "base_exception.h"
+#include "stacktrace.h"
 #include "main_window.h"
 #ifdef WIN32
 #   include <windows.h>
@@ -32,11 +36,48 @@
 #   include <CoreFoundation/CoreFoundation.h>
 #endif
 
-using std::string;
+#ifdef HAVE_EXECINFO_H
+#   include <signal.h>
+#   include <execinfo.h>
+#endif
+
+using namespace std;
+
 
+static void bt_sighandler(int);
+
+// Custom QApplication to catch and log exceptions properly
+// See http://forum.qtfr.org/viewtopic.php?id=7615
+class MyApplication : public QApplication
+{
+public:
+    MyApplication(int argc, char **argv)
+        : QApplication(argc, argv)
+    {}
+
+    virtual bool notify(QObject *receiver, QEvent *event)
+    {
+        try
+        {
+            return QApplication::notify(receiver, event);
+        }
+        catch (const BaseException &e)
+        {
+            cerr << "Exception caught: " << e.what() << endl;
+            cerr << e.getStackTrace() << endl;
+            return false;
+        }
+    }
+};
 
 int main(int argc, char **argv)
 {
+#ifdef HAVE_EXECINFO_H
+    // Install a custom signal handler to print a backtrace when crashing
+    // See http://www.linuxjournal.com/article/6391 for inspiration
+    signal(SIGSEGV, &bt_sighandler);
+#endif
+
     // On Mac, running Eliot from the dock does not automatically set the LANG
     // variable, so we do it ourselves.
     // Note: The following block of code is copied from VLC, and slightly
@@ -77,7 +118,7 @@
 #endif
 #endif
 
-    QApplication app(argc, argv);
+    MyApplication app(argc, argv);
     app.setWindowIcon(QIcon(":/images/eliot.xpm"));
 
 #ifdef ENABLE_NLS
@@ -121,3 +162,17 @@
     qmain.show();
     return app.exec();
 }
+
+#ifdef HAVE_EXECINFO_H
+static void bt_sighandler(int signum)
+{
+    cerr << "Segmentation fault!" << endl;
+    cerr << "Backtrace:" << endl;
+    cerr << StackTrace::GetStack() << endl;
+
+    // Restore the default handler to generate a nice core dump
+    signal(signum, SIG_DFL);
+    raise(signum);
+}
+#endif
+

Index: dic/base_exception.cpp
===================================================================
RCS file: dic/base_exception.cpp
diff -N dic/base_exception.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dic/base_exception.cpp      17 Oct 2010 21:23:40 -0000      1.1
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2010 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *****************************************************************************/
+
+#include "base_exception.h"
+#include "stacktrace.h"
+
+using namespace std;
+
+
+BaseException::BaseException(const string &iMessage)
+    : m_message(iMessage)
+{
+    m_stack = StackTrace::GetStack();
+}
+
+
+const char *BaseException::what() const throw()
+{
+    return m_message.c_str();
+}
+
+
+string BaseException::getStackTrace() const
+{
+    return m_stack;
+}
+

Index: dic/base_exception.h
===================================================================
RCS file: dic/base_exception.h
diff -N dic/base_exception.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dic/base_exception.h        17 Oct 2010 21:23:40 -0000      1.1
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2010 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *****************************************************************************/
+
+#ifndef BASE_EXCEPTION_H_
+#define BASE_EXCEPTION_H_
+
+#include <exception>
+#include <string>
+
+
+/**
+ * Base exception class for all the exception classes in Eliot.
+ * It provides a stack trace.
+ */
+class BaseException: public std::exception
+{
+    public:
+        BaseException(const std::string &iMessage);
+        ~BaseException() throw() {}
+        virtual const char *what() const throw();
+
+        std::string getStackTrace() const;
+
+    private:
+        std::string m_message;
+        std::string m_stack;
+};
+
+#endif

Index: dic/stacktrace.cpp
===================================================================
RCS file: dic/stacktrace.cpp
diff -N dic/stacktrace.cpp
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dic/stacktrace.cpp  17 Oct 2010 21:23:40 -0000      1.1
@@ -0,0 +1,91 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2010 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *****************************************************************************/
+
+#include "config.h"
+#include <sstream>
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+
+#include "stacktrace.h"
+
+#ifdef HAVE_EXECINFO_H
+#   include <execinfo.h>
+#endif
+#ifdef HAVE_GCC_ABI_DEMANGLE
+#   include <cxxabi.h>
+#endif
+
+using namespace std;
+
+
+string StackTrace::GetStack()
+{
+#if defined HAVE_EXECINFO_H && defined(DEBUG)
+    static const int MAX_FRAMES = 42;
+    void *frames[MAX_FRAMES];
+    // Get the frames
+    int nb = backtrace(frames, MAX_FRAMES);
+    // Get the corresponding symbols (ignoring the first frame)
+    char **symbols = backtrace_symbols(frames + 1, nb - 1);
+    // Demangle the symbols and build a nice stack trace
+    ostringstream oss;
+    for (int i = 0; i < nb - 1; ++i)
+    {
+        oss << "    at " << Demangle(symbols[i]) << endl;
+    }
+
+    return oss.str();
+#else
+    return "";
+#endif
+}
+
+
+// See http://tombarta.wordpress.com/2008/08/01/c-stack-traces-with-gcc/
+// and 
http://mykospark.net/2009/09/runtime-backtrace-in-c-with-name-demangling/
+// for more details
+string StackTrace::Demangle(char *symbol)
+{
+#if defined HAVE_GCC_ABI_DEMANGLE && defined(DEBUG)
+    char temp1[200];
+    char temp2[200];
+    if (sscanf(symbol, "%199[^(]%*[^_]%199[^)+]", temp1, temp2) == 2)
+    {
+        // Try to demangle a C++ name
+        int status;
+        char *demangled = abi::__cxa_demangle(temp2, NULL, NULL, &status);
+        if (demangled != NULL)
+        {
+            string result = temp1 + string(": ") + demangled;
+            free(demangled);
+            return result;
+        }
+        // Try to demangle a C name
+        else if (sscanf(symbol, "%199s", temp2) == 1)
+        {
+            return temp1 + string(": ") + temp2;
+        }
+    }
+
+    // Everything else failed, return the symbol
+#endif
+    return symbol;
+}

Index: dic/stacktrace.h
===================================================================
RCS file: dic/stacktrace.h
diff -N dic/stacktrace.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ dic/stacktrace.h    17 Oct 2010 21:23:40 -0000      1.1
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * Eliot
+ * Copyright (C) 2010 Olivier Teulière
+ * Authors: Olivier Teulière <ipkiss @@ gmail.com>
+ *
+ * This program 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.
+ *
+ * This program 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 this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *****************************************************************************/
+
+#ifndef STACK_TRACE_H_
+#define STACK_TRACE_H_
+
+#include <string>
+
+using std::string;
+
+
+class StackTrace
+{
+public:
+    static string GetStack();
+
+private:
+    static string Demangle(char *symbol);
+};
+
+#endif

Index: m4/ax_cxx_gcc_abi_demangle.m4
===================================================================
RCS file: m4/ax_cxx_gcc_abi_demangle.m4
diff -N m4/ax_cxx_gcc_abi_demangle.m4
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ m4/ax_cxx_gcc_abi_demangle.m4       17 Oct 2010 21:23:40 -0000      1.1
@@ -0,0 +1,58 @@
+# ===========================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_cxx_gcc_abi_demangle.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CXX_GCC_ABI_DEMANGLE
+#
+# DESCRIPTION
+#
+#   If the compiler supports GCC C++ ABI name demangling (has header
+#   cxxabi.h and abi::__cxa_demangle() function), define
+#   HAVE_GCC_ABI_DEMANGLE
+#
+#   Adapted from AX_CXX_RTTI by Luc Maisonobe
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Neil Ferguson <address@hidden>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 8
+
+AC_DEFUN([AX_CXX_GCC_ABI_DEMANGLE],
+[AC_CACHE_CHECK(whether the compiler supports GCC C++ ABI name demangling,
+ax_cv_cxx_gcc_abi_demangle,
+[AC_LANG_SAVE
+ AC_LANG_CPLUSPLUS
+ AC_TRY_COMPILE([#include <typeinfo>
+#include <cxxabi.h>
+#include <string>
+#include <cstdlib>
+
+template<typename TYPE>
+class A {};
+],[A<int> instance;
+int status = 0;
+char* c_name = 0;
+
+c_name = abi::__cxa_demangle(typeid(instance).name(), 0, 0, &status);
+
+std::string name(c_name);
+free(c_name);
+
+return name == "A<int>";
+],
+ ax_cv_cxx_gcc_abi_demangle=yes, ax_cv_cxx_gcc_abi_demangle=no)
+ AC_LANG_RESTORE
+])
+if test "$ax_cv_cxx_gcc_abi_demangle" = yes; then
+  AC_DEFINE(HAVE_GCC_ABI_DEMANGLE,1,
+            [define if the compiler supports GCC C++ ABI name demangling])
+fi
+])



reply via email to

[Prev in Thread] Current Thread [Next in Thread]