Quelqu'un sait-il d'un meilleur/plus rapide pour obtenir la pile d'appels que « StackWalk »? Je pense aussi que stackwalk peut aussi être plus lent sur les méthodes avec beaucoup de variables ... (je me demande ce que profileurs commerciales font?) J'utilise C++ sur Windows. :) merci :)plus vite que Stackwalk
Répondre
Je ne sais pas si c'est plus rapide, et il ne vous montrera aucun symbole, et je suis sûr que vous pouvez faire mieux que cela, mais c'est un code que j'ai écrit un certain temps quand je avais besoin de cette information (fonctionne uniquement pour 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;
}
}
Check out http://msdn.microsoft.com/en-us/library/bb204633%28VS.85%29.aspx - c'est "CaptureStackBackTrace", bien qu'il soit appelé "RtlCaptureStackBackTrace".
J'utilise Jochen Kalmbachs StackWalker
(http://stackwalker.codeplex.com/).
Je speedet it up
ainsi:
La plupart du temps est perdu dans la recherche de la
PDB files
dans les répertoires par défaut et les serveurs PDB.Je n'utilise que
one PDB path
et mis en œuvre unwhite list
pour les images que je veux se résoudre (pas besoin pour moi de chercher des user32.pdb)Parfois, j'ai besoin de plonger au fond, donc je a défini un
max deep
changements de code:
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)
{
...
}
}
La nouvelle version (supporti g VS2010) de StackWalker
est au Codeplex
. La documentation est toujours au CodeProject
.
Valgrind? http://stackoverflow.com/questions/413477/is-there-a-good-valgrind-substitute-for-windows – t0mm13b
hmmm ... n'est pas valgrind seulement pour unix? – Idov
et valgrind instrumentation, je cherche un meilleur moyen d'échantillonner la pile ... – Idov