Only for windows.
I want trace the call stack when ogre throw OgreException outof VS IDE sometimes .
I can use the DBGHELPER.dll to walk through callstack and get the symbo information.
So, I Need to get the CONTEXT from the exception point.
But I can't get this form catch point As Ogre use std::exception that has not CONTEXT.
So I make a modify to ogre exception:
OgreException.h:
change
#define OGRE_EXCEPT ....
to
#ifndef OGRE_EXCEPT #define OGRE_EXCEPT .... #endif
I can make a custom version OGRE_EXCEPT in OgreConfig.h to provide call stack trace now.
In OgreConfig.h
add
void DoExceptionCallStackTrace(const char* exception_description,const char* prefix_file_name); #define OGRE_EXCEPT(num, desc, src) do{ Ogre::String temp=desc; DoExceptionCallStackTrace(temp.c_str(),"Ogre exception"); throw Ogre::ExceptionFactory::create( Ogre::ExceptionCodeType<num>(), desc, src, __FILE__, __LINE__ );}while(0); #ifdef _DEBUG # pragma comment(lib,"CallStackTraceD.lib") #else # pragma comment(lib,"CallStackTrace.lib") #endif
CallStackTrace.lib include
DoExceptionCallStackTrace and Konstantin Boukreev's Sym_Engine
sym_engine.h coming from code project
DoExceptionCallStackTrace function:
#include <windows.h> #include <iostream> #include <sstream> #include <string> #include <fstream> #include <time.h> #include <algorithm> #include "sym_engine.h" static std::string getTimeString() { _tzset(); char temp1[128]; char temp2[128]; // Display operating system-style date and time. _strtime_s( temp1, 128 ); _strdate_s( temp2, 128 ); std::string result=temp2; result+=" "; result+=temp1; std::replace(result.begin(),result.end(),':','-'); std::replace(result.begin(),result.end(),'/','-'); return result; } void DoExceptionCallStackTrace(const char* exception_description,const char* prefix_file_name) { CONTEXT c; memset(&c, 0, sizeof(CONTEXT)); c.ContextFlags = CONTEXT_FULL; __asm call x __asm x: pop eax __asm mov c.Eip, eax __asm mov c.Ebp, ebp __asm mov c.Esp, esp std::stringstream ss(std::ios::out); sym_engine::stack_trace(ss,&c,1); std::string file_name=prefix_file_name; static int id=0; id++; char buf[16]; sprintf_s(buf,16," %04d ",id); file_name+=buf; file_name+=getTimeString(); file_name+=".txt"; std::fstream fs(file_name.c_str(),std::ios::out); fs<<exception_description; fs<<"\n"; fs<<"call stack:\n"; fs<<ss.str(); fs.close(); }
Now we run ogre out of IDE:
I can get a file named Ogre exception 0001 06-11-07 17-41-24.txt.
the file include:
Cannot locate resource varianceshadowcastervp.cg in resource group Effect or any other group. call stack: d:\work\ogre\ogrenew\ogremain\src\ogreresourcegroupmanager.cpp(602) : OgreMain_d.dll at Ogre::ResourceGroupManager::openResource() d:\work\ogre\ogrenew\ogremain\src\ogrehighlevelgpuprogram.cpp(152) : OgreMain_d.dll at Ogre::HighLevelGpuProgram::loadHighLevelImpl() d:\work\ogre\ogrenew\ogremain\src\ogrehighlevelgpuprogram.cpp(109) : OgreMain_d.dll at Ogre::HighLevelGpuProgram::loadHighLevel() d:\work\ogre\ogrenew\ogremain\src\ogrehighlevelgpuprogram.cpp(90) : OgreMain_d.dll at Ogre::HighLevelGpuProgram::createParameters() d:\work\ogre\ogrenew\ogremain\src\ogregpuprogram.cpp(320) : OgreMain_d.dll at Ogre::GpuProgram::getDefaultParameters() d:\work\ogre\ogrenew\ogremain\src\ogrematerialserializer.cpp(3131) : OgreMain_d.dll at Ogre::MaterialSerializer::finishProgramDefinition() d:\work\ogre\ogrenew\ogremain\src\ogrematerialserializer.cpp(3003) : OgreMain_d.dll at Ogre::MaterialSerializer::parseScriptLine() d:\work\ogre\ogrenew\ogremain\src\ogrematerialserializer.cpp(2864) : OgreMain_d.dll at Ogre::MaterialSerializer::parseScript() d:\work\ogre\ogrenew\ogremain\src\ogrematerialmanager.cpp(164) : OgreMain_d.dll at Ogre::MaterialManager::parseScript() d:\work\ogre\ogrenew\ogremain\src\ogreresourcegroupmanager.cpp(784) : OgreMain_d.dll at Ogre::ResourceGroupManager::parseResourceGroupScripts() d:\work\ogre\ogrenew\ogremain\src\ogreresourcegroupmanager.cpp(145) : OgreMain_d.dll at Ogre::ResourceGroupManager::initialiseAllResourceGroups() d:\work\code\gameclient\appframework\gameapplication.cpp(255) : GameClient.exe at GameApplication::loadResources() d:\work\code\gameclient\appframework\gameapplication.cpp(82) : GameClient.exe at GameApplication::setup() d:\work\code\gameclient\appframework\gameapplication.cpp(38) : GameClient.exe at GameApplication::go() d:\work\code\gameclient\gameclient.cpp(70) : GameClient.exe at main() f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c(597) : GameClient.exe at __tmainCRTStartup() f:\sp\vctools\crt_bld\self_x86\crt\src\crtexe.c(414) : GameClient.exe at mainCRTStartup() (0) : kernel32.dll at IsProcessorFeaturePresent()