有没有人知道更好/更快的方式获得调用堆栈而不是“StackWalk”? 我也认为对于有很多变量的方法,stackwalk也会变慢... (我想知道商业剖析师会做什么?) 我在Windows上使用C ++。 :) 谢谢:))
答案 0 :(得分:2)
我使用Jochen Kalmbachs StackWalker。
我speedet it up
这样:
在默认目录和PDB服务器中查找PDB files
时,大部分时间都会丢失。
我只使用one PDB path
并为我想要解析的图片实现了white list
(无需我查找user32.pdb)
有时候我不需要深入到底部,所以我定义了一个max deep
代码更改:
BOOL StackWalker::LoadModules()
{
...
// 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 )
{
...
}
}
答案 1 :(得分:1)
查看http://msdn.microsoft.com/en-us/library/bb204633%28VS.85%29.aspx - 这是“CaptureStackBackTrace”,虽然它被称为“RtlCaptureStackBackTrace”。
答案 2 :(得分:0)
我不知道它是否更快,并且它不会显示任何符号,我相信你可以做得更好,但这是我在一段时间内写的一些代码,当我需要这些信息时(仅适用于Windows):
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;
}
}