plus rapide que Stackwalk

Est-ce que quelqu’un connaît un moyen meilleur / plus rapide d’obtenir la stack 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 font les profileurs commerciaux?) J’utilise C ++ sous Windows. 🙂 Merci 🙂

Découvrez http://msdn.microsoft.com/en-us/library/bb204633%28VS.85%29.aspx – il s’agit de “CaptureStackBackTrace”, bien qu’il soit appelé “RtlCaptureStackBackTrace”.

J’utilise Jochen Kalmbachs StackWalker ( http://stackwalker.codeplex.com/ ).

Je l’ai speedet it up cette façon:

  • Le plus de temps est perdu dans la recherche des PDB files dans les répertoires par défaut et les serveurs PDB.

  • Je n’utilise qu’un one PDB path et j’ai implémenté une white list pour les images que je veux résoudre (inutile de chercher user32.pdb)

  • Parfois, je n’ai pas besoin de plonger au fond, alors j’ai défini un max deep

modifications 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(); ... } BOOL StackWalker::ShowCallstack(int iMaxDeep /* new parameter */ ... ) { ... // define a maximal deep // for (frameNum = 0; ; ++frameNum ) for (frameNum = 0; frameNum < iMaxDeep; ++frameNum ) { ... } } 

La dernière version (supporting VS2010) de StackWalker est sur Codeplex . La documentation est toujours sur CodeProject .

Je ne sais pas si c’est plus rapide, et cela 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 il y a quelque temps quand j’avais besoin de cette info Les fenêtres):

 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 comstackr 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; } }