No właśnie - stack trace wygląda w Javie bardzo ładnie... a w C++ nie. Można sobie napisać coś takiego, ale nie jest to ładne - wymaga dodatkowej linijki w każdej metodzie/funkcji ;)

Zaczynamy od jle.h:

#ifndef __jle_h__
#define __jle_h__

#include <exception>

#include <QStack>
#include <QString>

extern void stackPush(QString);
extern QStack<QString> getStack(void);

/**
 * Base class for other exceptions.
 *
 * @author Krzysiek Pawlik
 */
class Exception: public std::exception {

    protected:
        QString message;

    public:
        Exception(QString m) throw(): exception(), message(m) {}

        Exception(const Exception &e) throw(): exception(), message(e.message) {}

        virtual ~Exception() throw() {}

        QString getMessage() {
            return message;
        }

        void printStackTrace(void) {
            QStack<QString> q = getStack();
            if (q.isEmpty())
                return;
            fprintf(stderr, "%s\n", q.pop().toStdString().c_str());
            while (!q.isEmpty())
                fprintf(stderr, " from %s\n", q.pop().toStdString().c_str());
            fflush(stderr);
        }

};

#ifdef EBUG
#define TRACE { stackPush(QString("%1 [%2]").arg(__PRETTY_FUNCTION__).arg(__FILE__)); }
#else
#define TRACE
#endif

#endif

Następnie jle.cpp:

#include <QStack>
#include <QString>

static QStack<QString> stack;

void stackPush(QString aFunc) { stack.push(aFunc); }
QStack<QString> getStack(void) { return stack; }

Teraz wystarczy mały test:

#include <jle.h>

class TestClass {
    public:
        static void d(QString a) { TRACE throw Exception(a); }
};

namespace tttt {
    void c(int) { TRACE TestClass::d("AAA"); }
}

void b() { TRACE tttt::c(1); }
void a() { TRACE b(); }

int main(void) {

    TRACE

    try {
        a();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return 0;

}

Kompilować oczywiście należy toto z -DEBUG. Wynik jest taki:

static void TestClass::d(QString) [test.cxx]
 from void tttt::c(int) [test.cxx]
 from void b() [test.cxx]
 from void a() [test.cxx]
 from int main() [test.cxx]

Jedyna wada: makro TRACE.

Żeby to było można wykorzystać w projektach trzeba zrobić zdejmowanie ze stosu, hint: zmienne lokalne.

Kategorie: devel
Opublikowany: 25 listopada 2006, 13:41
Komentarze: 5 komentarzy
*ncpufreqd-2.2 (23 Nov 2006)

  23 Nov 2006; Krzysiek Pawlik <nelchael_AT_gentoo.org> +ncpufreqd-2.2.ebuild:
  Version bump.
Kategorie: devel
Opublikowany: 23 listopada 2006, 19:06
Komentarze: Dodaj komentarz

Yeah... right...

Kategorie: general
Opublikowany: 11 listopada 2006, 16:51
Komentarze: 3 komentarze