有人知道更好/更快的方式来获得调用堆栈比“StackWalk”? 我也认为stackwalk也可以在variables很多的方法上变慢…(我想知道什么是商业剖析器?)我在Windows上使用C ++。 :) 谢谢 :)
看看http://msdn.microsoft.com/en-us/library/bb204633%28VS.85%29.aspx – 这是“CaptureStackBackTrace”,虽然它被称为“RtlCaptureStackBackTrace”。
我使用Jochen Kalmbachs StackWalker
( http://stackwalker.codeplex.com/ )。
我这样说:
在寻找默认目录和PDB服务器中的PDB files
,大部分时间都会丢失。
我只使用one PDB path
并为我想要解决的图像实现了一个white list
(不需要我去查找user32.pdb)
有时我不需要max deep
底部,所以我定义了一个max deep
代码更改:
BOOL StackWalker::Loadmodulees() { ... // comment this line out and replace to your pdb path // BOOL bRet = this->m_sw->Init(szSymPath); BOOL bRet = this->m_sw->Init(<my pdb path>); ... } BOOL StackWalker::ShowCallstack(int iMaxDeep /* new parameter */ ... ) { ... // define a maximal deep // for (frameNum = 0; ; ++frameNum ) for (frameNum = 0; frameNum < iMaxDeep; ++frameNum ) { ... } }
StackWalker
的最新版本(supportig VS2010)在Codeplex
。 文档还是在CodeProject
。
我不知道它是否更快,它不会显示任何符号,我相信你可以做的比这更好,但是这是我写了一些代码,当我需要这个信息(只适用于视窗):
struct CallStackItem { void* pc; CallStackItem* next; CallStackItem() { pc = NULL; next = NULL; } }; typedef void* CallStackHandle; CallStackHandle CreateCurrentCallStack(int nLevels) { void** ppCurrent = NULL; // Get the current saved stack pointer (saved by the compiler on the function prefix). __asm { mov ppCurrent, ebp }; // Don't limit if nLevels is not positive if (nLevels <= 0) nLevels = 1000000; // ebp points to the old call stack, where the first two items look like this: // ebp -> [0] Previous ebp // [1] previous program counter CallStackItem* pResult = new CallStackItem; CallStackItem* pCurItem = pResult; int nCurLevel = 0; // We need to read two pointers from the stack int nRequiredMemorySize = sizeof(void*) * 2; while (nCurLevel < nLevels && ppCurrent && !IsBadReadPtr(ppCurrent, nRequiredMemorySize)) { // Keep the previous program counter (where the function will return to) pCurItem->pc = ppCurrent[1]; pCurItem->next = new CallStackItem; // Go the the previously kept ebp ppCurrent = (void**)*ppCurrent; pCurItem = pCurItem->next; ++nCurLevel; } return pResult; } void PrintCallStack(CallStackHandle hCallStack) { CallStackItem* pCurItem = (CallStackItem*)hCallStack; printf("----- Call stack start -----\n"); while (pCurItem) { printf("0x%08x\n", pCurItem->pc); pCurItem = pCurItem->next; } printf("----- Call stack end -----\n"); } void ReleaseCallStack(CallStackHandle hCallStack) { CallStackItem* pCurItem = (CallStackItem*)hCallStack; CallStackItem* pPrevItem; while (pCurItem) { pPrevItem = pCurItem; pCurItem = pCurItem->next; delete pPrevItem; } }