Callstack Trace



  • Hi,

    ich wollte mir mal einen kleinen Callstack Tracer in meine Engine einbauen, funktioniert auch recht gut, nur unter manchen Bedingungen geht er nicht. 😞

    So sieht der Tracer aus:

    #ifdef _DEBUG
    namespace AGE { AGEAPI void TraceFunction(const char*); }
    #define GUARD(Function) static const char *AGEDbg_FunctionName = #Function; try {
    #define UNGUARD } catch(...) { MessageBox(NULL, AGEDbg_FunctionName, "Exception jetzt in:", MB_OK); AGE::TraceFunction(AGEDbg_FunctionName); throw; }
    #endif
    
    // ... im Namespace AGE
    #ifdef _DEBUG
    
    AGEAPI void TraceFunction(const char *pchFunctionName);
    
    class CallStackEnumerator
    {
    public:
        AGEAPI CallStackEnumerator(void);
        AGEAPI ~CallStackEnumerator(void);
    
        AGEAPI const char *Enumerate(void);
    
    private:
        std::vector<const char*>::iterator m_Iterator;
    };
    
    #endif
    
    // ... Implementation
    
    #ifdef _DEBUG
    
    std::vector<const char*> g_StackTrace;
    
    void AGE::TraceFunction(const char *pchFunctionName)
    {
        g_StackTrace.push_back(pchFunctionName);
    }
    
    CallStackEnumerator::CallStackEnumerator(void) :
    m_Iterator(g_StackTrace.end() - 1)
    {}
    
    CallStackEnumerator::~CallStackEnumerator(void)
    {
        g_StackTrace.clear();
    }
    
    const char *CallStackEnumerator::Enumerate(void)
    {
        if (m_Iterator < g_StackTrace.begin())
            return 0;
    
        return *m_Iterator--;
    }
    
    #endif
    

    Wie gesagt, das funktioniert auch eigentlich ganz gut (GUARD & UNGUARD werden logischerweise in jede Funktion eingefügt).
    Nur klappt es hier z.B. nicht, eigentlich müsste der Callstack so aussehen:
    Mainloop -> Kernel::~Kernel -> PluginManager::~PluginManager -> PluginManager::UnloadAll -> PluginManager::Plugin::~Plugin -> AGEUnload -> Exception!

    Mainloop ist dabei in der EXE, die meine Engine verwendet ("Techdemo"), AGEUnload in dem eigentlichen Plugin (dynamisch geladen von der Engine) und der Rest dazwischen in der Engine-DLL (statisch gelinkt zur Techdemo).

    Aber er sieht so aus:
    Mainloop -> PluginManager::Plugin::~Plugin -> AGEUnload -> Exception!

    Also irgendwie werden alle Funktionen der Engine-DLL außer dem Destruktor von PluginManager::Plugin übersprungen. 😞

    Die Engine-DLL wird natürlich als Debugversion mit _DEBUG definiert kompiliert, sonst wäre ja auch der Destruktor nicht im Callstack Trace gespeichert.

    Hat jemand eine Idee, woran das liegen könnte?

    ChrisM

    EDIT: PS: Die Messagebox in UNGUARD() dient nur dem Debugging und sie kommt auch nicht für die fehlenden Funktionen!

    [ Dieser Beitrag wurde am 19.06.2003 um 10:53 Uhr von ChrisM editiert. ]



  • Hat sich geklärt, der Fehler lag woanders.

    ChrisM


Anmelden zum Antworten